同步 & 非同步(5) - Promise.all 與 並行


Posted by TempuraEngineer on 2023-07-24

目錄


奇怪的問題

最近遇到了一個奇怪的問題,記錄一下

這個問題是後端說同個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()


#Promise #concurrency #sequence #並行 #序列







Related Posts

ClearDB id 連續遞增問題

ClearDB id 連續遞增問題

MTR04_0619

MTR04_0619

那些 React 跟 Redux 在一起的日子

那些 React 跟 Redux 在一起的日子


Comments