有一系列的承诺,在我需要从数据库获取他的组和构造函数名称之后,第一个从数据库获取用户的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它与其他函数不同 (在其余的简单数据库请求中)
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);
});
});
有可能简化这个吗? 我很感激
答案 0 :(得分:1)
考虑使用真实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);
}
并确保avoid the Promise
constructor antipattern
async function takeNamesCycle(arr, obj) {
for (const idg of arr) {
const names = await takeNames(idg);
obj.idg[idg] = names;
}
return obj;
}
答案 1 :(得分:0)
发布的代码混合了代码中的await
和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
处理程序。
承诺拒绝
如果等待的promise被拒绝,await
运算符会抛出拒绝原因,而不会恢复函数执行。
可以在try / catch块中捕获拒绝,以便忽略错误,重复操作或将其替换为由应用程序要求确定的不同操作。 E.G。
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
}
另一方面,如果拒绝被视为致命,请不要将await
放入try/catch
块中 - 抛出的值将被捕获并用于拒绝由异步函数,就像在then
或catch
处理程序中抛出错误一样。
如果嵌套了对异步函数的调用,每个函数都使用await
调用而没有任何try/catch
块,则拒绝错误将从深层嵌套函数中冒出来并拒绝最外层异步函数调用返回的promise。最外层承诺上的单个.catch
子句可用于防止未被捕获的承诺拒绝并通知发生故障。
<强>结论强>
如果您更熟悉该语法,请尝试使用普通的承诺链编写代码。一定要继续将其转换为async / await语法,但要注意async/await
是替代语法,并且它们不能在同一个函数中很好地混合。正如@Bergi已经说过的那样,从异步函数返回一个新的promise是一种反模式 - 异步函数已经返回一个承诺。