簡體   English   中英

承諾與周期

[英]Promises and cycles

這里有一系列的承諾,第一個是我需要從數據庫中獲取用戶的組名和構造函數的名稱之后,才從數據庫中獲取用戶的ID。這些可以是多個副本,因此可能會進入一個周期。 最終我只收到一個用戶的對象

 async(takeIds() .then(ids => { // console.log("ids", ids); for (var i = 0; i < ids.length; i++) { data.id = ids[i]; await (takeIdvk(ids[i]) .then(idm => { data.idvk = idm; takeIdg(data.id) .then(res => { takeNamesCycle(res, data) .then(data => { console.log("data", data); }) .catch(err => { console.log(err); }); }) .catch(err => { console.log(err); }); }) .catch(err => { console.log(err); })); } }) .catch(function(err) { console.log(err); })); 

函數takeNamesCycle cos與其他函數有所不同(在其余對數據庫的簡單請求中)

 var takeNamesCycle = async(function(arr, obj) { return new Promise((resolve, reject) => { for (var i = 0; i < arr.length; i++) { var idg = arr[i]; await (takeNames(arr[i]) .then(names => { obj.idg[idg] = names; }) .catch(err => { console.log(err); })); } resolve(obj); }); }); 

有可能簡化嗎? 我會很感激

考慮使用真正的async / await語法,而不是使用具有async()await()函數的庫。

const ids = await takeIds();
// console.log("ids", ids);
try {
  for (var i = 0; i < ids.length; i++) {
    data.id = ids[i];
    const idem = await takeIdvk(ids[i]);
    data.idvk = idm;
    const res = await takeIdg(data.id);
    console.log("data", await takeNamesCycle(res, data));
  }
} catch(err) {
  console.log(err);
}

並確保避免Promise構造函數反模式

async function takeNamesCycle(arr, obj) {
  for (const idg of arr) {
    const names = await takeNames(idg);
    obj.idg[idg] = names;
  }
  return obj;
}

發布的代碼在await代碼中混合了promise鏈樣式,在錯誤代碼中混合了async函數。

首先await不允許.then還是.catch方法要在它返回值調用。 原因是await返回的值永遠不會是一個承諾。 await僅在成功的promise操作之后恢復執行,並返回操作結果。 所以舉個例子

await (takeIdvk(ids[i])
.then(idm => {           // incorrect
     data.idvk = idm;
     // ... more code

let idm = await takeIdvk(ids[i])   // await returns fulfilled value
data.idvk = idm;
// ... more code

后,換句話說,代碼來處理數據對一個成功的操作被內聯寫入await ,而不是在一個單獨的onfulfilled作為參數傳遞的處理程序.then

承諾拒絕

如果正在等待的承諾被拒絕,則await操作員將拋出拒絕原因,而無需恢復函數執行。

拒絕可以捕獲在try / catch塊中,以便忽略該錯誤,重復該操作或將其替換為根據應用程序要求確定的其他操作。 例如

let idm;
try {
    idm = await takeIdvk(ids[i])   // await returns fulfilled value
    data.idvk = idm;
    // ... more code
} catch( err) {
    console.log( "ignoring error + err);
    // the value of idm is undefined
}

另一方面,如果拒絕被認為是致命的,則不要在try/catch塊中await -拋出的值將被捕獲並用於拒絕由異步函數返回的promise,就像在then拋出錯誤一樣。或catch處理程序。

如果嵌套了對異步函數的調用,每個調用都使用await進行了調用,而沒有任何try/catch塊,則拒絕錯誤將從深度嵌套的函數中冒出來,並拒絕最外層異步函數調用返回的promise。 最外層promise的單個.catch子句可用於防止未捕獲的promise拒絕並通知發生了故障。

結論

如果您更熟悉該語法,請嘗試使用普通的Promise鏈編寫代碼。 一定要繼續將其轉換為async / await語法,但要注意async/await是一種替代語法,它們在同一函數中混合得不好。 如@Bergi所述,從異步函數返回新的Promise是一種反模式-異步函數已經返回了Promise。

暫無
暫無

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

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