繁体   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