目錄
奇怪的問題
最近遇到了一個奇怪的問題,記錄一下
這個問題是後端說同個API連打4次
,但是前一次還沒完成後一次就開始
,導致失敗
前端這邊一開始的寫法是用Promise.all,後來改遞迴就可以了,到底是為什麼呢🤔
並行 & 平行
這個問題要先說序列(sequence)、並行(concurrency)和平行(parallel)是什麼,直接看下圖吧
(contribute to JavaScript in Plain English)
回歸到問題,前一次還沒完成後一次就開始
,導致失敗,也就是說非序列
的寫法都會失敗
,而遞迴是序列
,所以才能成功
因為Promise一被建立後就會開始處理
,所以事實上Promise.all的處理順序會是並行
的
至於平行的話不用管,因為Javascript是單執行緒的語言,所以不會出現平行的情況
例子
- 並行
const packageNames = ['vuejs', 'reactjs', 'angular'];
const getPackageInfo = async(packageName) => {
console.log(`${packageName} start`);
return await fetch(`https://api.github.com/orgs/${packageName}`).then((d) => {
console.log(`${packageName} complete`);
return d.json();
});
}
// concurrency
const packageInfos = await Promise.all([packageNames.map((name) => getPackageInfo(name))]);
- 序列
// sequence
await getPackageInfo('vuejs');
await getPackageInfo('reactjs');
// sequence
const packageNames = ['vuejs', 'reactjs', 'angular'];
const getPackageInfos = async (index) => {
if(index > packageNames.length -1 ){
return;
}
console.log(`${packageNames[index]} start`);
return await fetch(`https://api.github.com/orgs/${packageNames[index]}`).then((d) => {
console.log(`${packageNames[index]} complete`);
return d.json();
}).finally(() => {
getPackageInfos(index + 1);
});
}
const packageInfos = await getPackageInfos(0);
參考資料
Does Promise.all Execute in Parallel? How Promise.all Works in JavaScript
Promise.all()