Js 异步场景总结和一些优质代码展示

js-异步场景总结和一些优质代码展示

简介


Generator 的主要用途是实现异步编程,因此常用于客户端和服务端的异步操作中。以下是一些常见的使用场景:

  1. 客户端:在客户端中,Generator 可以用于处理复杂的用户交互逻辑、动画效果等。例如,在一个需要用户输入多个步骤的表单中,可以使用 Generator 来暂停函数的执行,等待用户完成当前步骤后再继续执行下一步。

  2. 服务端:在服务端中,Generator 可以用于处理复杂的异步操作,例如数据库查询、文件读写等。通过使用 Generator,可以避免回调地狱的问题,并使异步代码更加易读易维护。

需要注意的是,现在已经有更加简洁易用的异步编程方式,例如 async/await,因此在实际开发中,使用 Generator 的场景可能会相对较少。不过,如果你想深入了解 JavaScript 异步编程的原理和实现方式,学习 Generator 仍然是非常有价值的。


在前端中,Generator 可以用于异步编程,可以通过使用 yield 关键字来暂停函数的执行,并且可以在需要时恢复执行。这样可以避免使用回调函数和 Promise 等方式来处理异步操作,使代码更加简洁易读。

下面是一个简单的例子,演示了如何使用 Generator 实现异步编程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function* fetchData() {
  const response = yield fetch('https://jsonplaceholder.typicode.com/todos/1');
  const data = yield response.json();
  console.log(data);
}

const generator = fetchData();
const promise = generator.next().value;

promise.then(response => {
  return generator.next(response).value;
}).then(data => {
  generator.next(data);
});

在上面的例子中,fetchData 函数定义了一个 Generator,其中包含了两个异步操作:第一个操作是使用 fetch 方法获取数据,第二个操作是将获取到的数据转换成 JSON 格式。通过使用 yield 关键字,我们可以在每个异步操作完成后暂停函数的执行,并将结果传递给下一个异步操作。在主程序中,我们首先获取 Generator 的实例,并调用 next 方法,以启动第一个异步操作。接着,我们使用 then 方法来处理异步操作的结果,并将结果传递给下一个异步操作,以此类推,直至所有异步操作完成。

需要注意的是,Generator 在前端中的应用并不常见,因为现代浏览器已经支持了更加简洁易用的异步编程方式,例如 async/await。


惰性计算通常用于处理大量数据或者需要频繁操作的数据集合,以避免不必要的计算和内存占用。以下是一些可能会用到惰性计算的业务场景:

  1. 数据库查询:当需要查询大量数据时,可以使用惰性计算来避免一次性将所有数据都加载到内存中,而是在需要时逐个获取数据。

  2. 数据流处理:当需要对数据流进行处理时,可以使用惰性计算来避免一次性将所有数据都加载到内存中,而是在需要时逐个处理数据。

  3. 图像处理:当需要处理大量图像时,可以使用惰性计算来避免一次性将所有图像都加载到内存中,而是在需要时逐个处理图像。

  4. 日志处理:当需要处理大量日志时,可以使用惰性计算来避免一次性将所有日志都加载到内存中,而是在需要时逐个处理日志。

总之,如果你需要处理大量数据或者需要频繁操作的数据集合,那么惰性计算可能是一个非常有用的工具,可以帮助你节省内存和提高效率。

惰性计算

示例

以下是一个使用 Generator 实现的惰性计算示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
function* lazyFilter(arr, predicate) {
  for (let i = 0; i < arr.length; i++) {
    if (predicate(arr[i])) {
      yield arr[i];
    }
  }
}

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const evenNumbers = lazyFilter(numbers, num => num % 2 === 0);

for (let number of evenNumbers) {
  console.log(number);
}

在这个示例中,我们定义了一个 lazyFilter 生成器函数,它接受一个数组和一个用于过滤元素的谓词函数。在 lazyFilter 函数内部,我们使用 for 循环遍历数组,并在满足谓词函数的条件时使用 yield 关键字将当前元素返回。这样,我们可以通过调用 lazyFilter 函数来创建一个惰性计算的迭代器对象,而不必立即对整个数组进行计算。最后,我们通过 for...of 循环遍历迭代器对象,并依次输出符合条件的元素。

需要注意的是,这个示例只是一个简单的惰性计算示例,实际应用中可能需要更复杂的逻辑和处理方式。

数据库查询

假设我们有一个包含用户信息的数据库,我们可以使用惰性计算来实现查询操作。首先,我们定义一个函数 getUserById,它接收一个用户ID作为参数,并返回一个函数,该函数会在调用时查询数据库并返回对应的用户信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const getUserById = (id) => {
  let user = null;
  return () => {
    if (!user) {
      console.log(`Querying database for user ${id}`);
      // 假设这里是查询数据库的代码
      user = { id, name: 'Alice', age: 25 };
    }
    return user;
  };
};

// 使用惰性计算查询用户信息
const user = getUserById(123)();
console.log(user);

数据流处理

假设我们有一个数据流,其中包含一些数字。我们可以使用惰性计算来实现对这些数字进行过滤和转换的操作。首先,我们定义一个函数 filter,它接收一个过滤函数作为参数,并返回一个函数,该函数会在调用时对数据流进行过滤。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const filter = (predicate) => {
  return (data) => {
    console.log(`Filtering data stream`);
    return data.filter(predicate);
  };
};

// 使用惰性计算过滤数据流
const data = [1, 2, 3, 4, 5];
const filteredData = filter(x => x % 2 === 0)(data);
console.log(filteredData);

在这个示例中,我们使用惰性计算来避免对整个数据流进行过滤,而是只在需要时才进行计算。

图像处理

假设我们有一个图像,我们可以使用惰性计算来实现对图像进行缩放和旋转的操作。首先,我们定义一个函数 scale,它接收一个缩放比例作为参数,并返回一个函数,该函数会在调用时对图像进行缩放。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const scale = (factor) => {
  let image = null;
  return () => {
    if (!image) {
      console.log(`Loading image`);
      // 假设这里是加载图像的代码
      image = { width: 100, height: 100 };
    }
    console.log(`Scaling image by factor ${factor}`);
    return { width: image.width * factor, height: image.height * factor };
  };
};

// 使用惰性计算缩放图像
const scaledImage = scale(2)();
console.log(scaledImage);

在这个示例中,我们使用闭包来保存图像信息,以便在下一次缩放时可以直接返回,而不必重新加载和处理图像。

日志处理

假设我们有一个应用程序,我们可以使用惰性计算来实现对日志进行记录和过滤的操作。首先,我们定义一个函数 log,它接收一个日志级别作为参数,并返回一个函数,该函数会在调用时记录日志。

1
2
3
4
5
6
7
8
9
const log = (level) => {
  return (...args) => {
    console.log(`[${level}]`, ...args);
  };
};

// 使用惰性计算记录日志
const debug = log('DEBUG');
debug('Debug message');

在这个示例中,我们使用惰性计算来避免在不需要记录日志时进行计算,从而提高程序的性能和效率。

updatedupdated2023-06-092023-06-09