JS基础 - 异步进阶 - 异步循环

前端开发·教程·资源 · 2022-06-25

我们写代码的时候,通常希望代码能按照我们写的顺序来执行;例如:

async function add(x) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(x + x);
        }, 1000);
    });
}
!(async function () {
    let arr = [5, 6, 7];
    arr.forEach(async (item) => {
        console.log(await add(item));
    });
})()

我们更希望上边的输出9结果为按顺序依次等待1秒后输出,但是,真实情况是 一起等待了1秒后一次性输出了。

1.for-of

async function add(x) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(x + x);
        }, 1000);
    });
}
!(async function () {
    let arr = [5, 6, 7];
    for (const item of arr) {
        console.log(await add(item)); // 多个任务成功地按照顺序执行
    }
})()

for...of采用的是通过 迭代器 去遍历。 首先,对于数组来讲,它是一种可迭代数据类型。那什么是可迭代数据类型呢?

可迭代数据类型:原生具有[Symbol.iterator]属性数据类型为可迭代数据类型。如数组、类数组(如arguments、NodeList)、Set和Map。

2.for await of (ES9)

  • ES9 (ECMAscript 2018))新增了异步迭代for await...of方法,为了解决数组中的元素都是promise对象无法遍历的问题。
  • 作用是循环等待每个Promise对象变为resolved状态才进入下一步。
  • 该循环遍历异步可迭代对象以及同步可迭代对象,包括: 内置的 String, Array,类似数组对象 (例如 argumentsNodeList),TypedArray, Map, Set 和用户定义的异步/同步迭代器。
  • 类似于 await 运算符一样,该语句只能在一个async function 内部使用。

    function fn(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(`${time}毫秒后输出成功!`);
            }, time);
        });
    }
    async function asyncFn() {
        const arr = [ this.fn(3000),this.fn(1000),this.fn(2000),this.fn(500)]; // Promise 数组
        for await (let x of arr) {
            console.log(x); // 输出的是resolved后的值
        }
    }
    asyncFn()

3.for-offor await of的区别

for-of是用来遍历同步操作的

for-of里面用await,会依次等待,顺序输出

for await of 是可以对异步集合进行操作

ECMAScript Javascript笔记 Promise ES9 for-of for await of
Theme Jasmine by Kent Liao