簡體   English   中英

這種類型的 promise 嵌套是好習慣嗎?

[英]Is this type of promise nesting good practice?

我只是想知道在這個例子中嵌套承諾是否被認為是好的做法,還是有更好的選擇?

getDatabaseModel.searchId(idNoms).then(function([noms, elements]) {
        getDatabaseModel.getLocalisations().then(function(localisations){
            getDatabaseModel.getStates().then(function(states){
                //Some code
            })
        })
    })

承諾避免回調地獄,但他們也不太擅長。 人們喜歡 Promise,直到他們發現 async/await。 完全相同的代碼可以在 async/await 中重寫為

async getModel(idNoms){
  const [noms, elements] = await getDatabaseModel.searchId(idNoms);
  const localisations = await getDatabaseModel.getLocalisations();
  const state = await getDatabaseModel.getStates():
  // do something using localisations & state, it'll work

}

getModel(idNoms);

這里學習 async/await

顯然,您的承諾是獨立的。 所以你應該使用Promise.all()讓它以最高性能並行運行。

Promise.all() 方法將一個可迭代的 Promise 作為輸入,並返回一個 Promise 解析為輸入 Promise 的結果數組

var searchById = getDatabaseModel.searchId(idNoms);
var getLocalisations = getDatabaseModel.getLocalisations();
var getStates = getDatabaseModel.getStates();

var result = Promise.all([searchById, getLocalisations, getStates]);
result.then((values) => {
  console.log(values);
});

例如,假設每個 promise 需要 1 秒 - 所以總共應該是 3 秒,但是對於Promise.all ,實際上總共只需要 1 秒。

 var tick = Date.now(); const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}`); log("Staring... "); var fetchData = (name, ms) => new Promise(resolve => setTimeout(() => resolve(name), ms)); var result = Promise.all( [ fetchData("searchById", 1000), fetchData("getLocalisations", 1000), fetchData("getStates", 1000) ]); result.then((values) => { log("Complete..."); console.log(values); });

此外,如果您擔心async/await更優雅/簡潔/像同步代碼一樣閱讀它,那么await關鍵字多說代碼應該等到異步請求完成,然后再執行下一個事情 雖然這些承諾是獨立的。 所以promise.all比你的情況要好。

 var tick = Date.now(); const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}`); var fetchData = (name, ms) => new Promise(resolve => setTimeout(() => resolve(name), ms)); Run(); async function Run(){ log("Staring... "); var a = await fetchData("searchById", 1000); var b = await fetchData("getLocalisations", 1000); var c = await fetchData("getStates", 1000); log("Complete..."); console.log([a, b, c]); }

IMO 有點難以閱讀和理解。 與此比較:

getDatabaseModel.searchId(idNoms)
    .then(([noms, elements]) => getDatabaseModel.getLocalisations())
    .then(localization => getDatabaseModel.getStates());

正如@deceze 指出的,有兩點需要注意:

  • 這些函數被串行調用
  • 它們似乎並不相互依賴,因為根本沒有使用nomselementslocalization

使用Promise.all ,您可以隨意混合搭配:


// Call `searchId` and `getState` at the same time
// Call `getLocalisations` after `searchId` is done
// wait for all to finish
Promise.all([
  getDatabaseModel.searchId(idNoms).then(([noms, elements]) => getDatabaseModel.getLocalisations()),
  getDatabaseModel.getStates()
]).then(([result1, result2]) => console.log('done'));


// Call all 3 at the same time
// wait for all to finish
Promise.all([
  getDatabaseModel.searchId(idNoms),
  getDatabaseModel.getLocalisations(),
  getDatabaseModel.getStates(),
]).then(([result1, result2, result3]) => console.log('done'));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM