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