songEagle

STAY CURIOUS. STAY HUMBLE.

【异步编程系列】async/await在for循环里运行结果怎么样?

经验分享 2019年09月06日 星期五 上午

一、前言

简单的async/await使用,将异步改成同步,如果在循环中使用async会怎么样?

二、需求

需求是这样的:异步获取数组这种的数组中元素

我们首先写一个:

var nums = [0,1,2,3,4,5];
var getNumByIndex = index => {
    return new Promise(resolve => {
       setTimeout(() => resolve(nums[index]), 1000);
    })
}

二、在for循环中await

async function forAwait(){
    console.log('循环开始');
    for(let i = 0;i<nums.length;i++){
       var value = await getNumByIndex(i);
       console.log(value);
    }
    console.log('循环结束');
}

执行结果:

循环开始
0
1
2
3
4
5
循环结束

可以看出for循环中,await是串行的。

发现for of,for in, while这些循环中是相同的。

四、在forEach里使用await

async function forEachAwait(){
    console.log('循环开始')
    nums.forEach(async num => {
        const value = await getNumByIndex(num);
        console.log(value)
    });
    console.log('循环结束')
}

输出:

循环开始
循环结束
0
1
2
3
4
5

为啥forEach的不能异步变同步呢?主要是:forEach是直接调用回调函数,for of等其他的是通过迭代器方式去遍历。

五、在map中使用await

我们先用 map 来运行上面的例子。

async function mapAwait(){
    console.log('循环开始');
    var numPromises = nums.map(async num => {
        var value = await getNumByIndex(num);
        console.log(value);
        return value;
    });
    var result = await Promise.all(numPromises);
    console.log('循环结束');
}

结果:

循环已经开始了
0
1
2
3
4
5
循环已经结束了

在map中使用await,会返回一个promises数组,因为async函数总会返回一个promise,我们需要拿到异步函数的值就需要await Promise.all()。

六、总结

如果你希望串行执行异步,你最好使用for循环之类的循环,如果你想拿到所有的异步值,使用map也是可以的,通过Promise.all()方法,如果不关心返回的结果,使用forEach也是可以的。

还没有评论,快来抢沙发吧!

本站总访问量 本站访客数人次