[英]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);
}
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.