Javascript async loop

Javascript 自ES7後支援潮潮的async-await語法,解決的許多不順眼的promise同步語法,

但是Array.prototype.forEach是沒有支援到async function的用法哦~ (天真的踩雷

底下給了一些程式片段範例:

首先為了例子方便,我封裝了一個setTimeout,這個wait(ms)傳進要等待的時間,並且執行完後回傳一個promise,等等我們會用async-await來處理它。

1
2
3
4
5
function wait (ms) {
return new Promise(function (resolve, reject) {
setTimeout(resolve, ms);
});
}

forEach

我們期望程式開始後每隔1000ms log出一個陣列值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function run () {
console.log('Start');
console.time('ExecuteTime');

var arr = ['apple', 'ball', 'cat', 'dog', 'egg'];

arr.forEach(async function (item) {
console.log(item);
await wait(1000);
});

console.log('End');
console.timeEnd('ExecuteTime'); // ExecuteTime: < 5ms
}

run();

執行上面程式可以發現我們的wait完全沒等到,程式就結束了,總執行時間很短。

for-of

於是我們將程式修改成下面這種寫法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
async function run () {
console.log('Start');
console.time('ExecuteTime');

var arr = ['apple', 'ball', 'cat', 'dog', 'egg'];

for (var item of arr) {
console.log(item);
await wait(1000);
}

console.log('End');
console.timeEnd('ExecuteTime'); // ExecuteTime: 5xxx ms
}

run();

執行上面程式後,符合我們的期望每隔1秒輸出一個陣列值。

How to break in forEach

NO.

在forEach裡沒辦法使用break,只能return;來跳過本次循環,有這種需求只能乖乖用for loop了。

或是參考底下連結提供的一些神奇解法。

推薦文章