简体   繁体   English

承诺与周期

[英]Promises and cycles

There's a chain of promises, the first takes user's id from data base after i need to get his groups and names of constructor from data base And these can be multiple copies As a result cycle into cycle. 这里有一系列的承诺,第一个是我需要从数据库中获取用户的组名和构造函数的名称之后,才从数据库中获取用户的ID。这些可以是多个副本,因此可能会进入一个周期。 eventually I receive object only of one user 最终我只收到一个用户的对象

 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); })); 

And function takeNamesCycle cos it differs from other ( in the rest simple requests to data base) 函数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); }); }); 

Is it possible to simplify this? 有可能简化吗? I'd be grateful 我会很感激

Consider using real async / await syntax instead of a library with async() and await() functions. 考虑使用真正的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);
}

and make sure to avoid the Promise constructor antipattern 并确保避免Promise构造函数反模式

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

The posted code is mixing promise chain style of code within await and async functions within bad code. 发布的代码在await代码中混合了promise链样式,在错误代码中混合了async函数。

First await does not permit .then or .catch methods to be called on the value it returns. 首先await不允许.then还是.catch方法要在它返回值调用。 The reason is that the value returned by await is never a promise. 原因是await返回的值永远不会是一个承诺。 await only resumes execution after a successful promise operation and returns the result of the operation. await仅在成功的promise操作之后恢复执行,并返回操作结果。 So for example 所以举个例子

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

becomes

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

In other words, code to handle data for a successful operation is written inline after await instead of in a separate onfulfilled handler passed as a parameter to .then . 后,换句话说,代码来处理数据对一个成功的操作被内联写入await ,而不是在一个单独的onfulfilled作为参数传递的处理程序.then

Promise Rejections 承诺拒绝

If the promise being waited on becomes rejected, the await operator throws the rejection reason without resuming function execution. 如果正在等待的承诺被拒绝,则await操作员将抛出拒绝原因,而无需恢复函数执行。

The rejection can be caught in a try/catch block in order to ignore the error, repeat the operation, or replace it with a different operation as determined by application requirements. 拒绝可以捕获在try / catch块中,以便忽略该错误,重复该操作或将其替换为根据应用程序要求确定的其他操作。 EG 例如

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
}

On the other hand, if rejection is to be considered fatal don't put await inside a try/catch block - the thrown value will be caught and used to reject the promise returned by the async function, much like throwing an error inside a then or catch handler. 另一方面,如果拒绝被认为是致命的,则不要在try/catch块中await -抛出的值将被捕获并用于拒绝由异步函数返回的promise,就像在then抛出错误一样。或catch处理程序。

If calls to async functions are nested, each called using await without any try/catch blocks, rejection errors will bubble up from deeply nested functions and reject the promise returned by the outermost async function call. 如果嵌套了对异步函数的调用,每个调用都使用await进行了调用,而没有任何try/catch块,则拒绝错误将从深度嵌套的函数中冒出来,并拒绝最外层异步函数调用返回的promise。 A single .catch clause on the outermost promise can be used to prevent uncaught promise rejections and notify that a failure occurred. 最外层promise的单个.catch子句可用于防止未捕获的promise拒绝并通知发生了故障。

Conclusion 结论

Try writing the code using plain promise chains if you are more familiar with that syntax. 如果您更熟悉该语法,请尝试使用普通的Promise链编写代码。 By all means continue with converting it to async/await syntax but be aware that async/await is an alternative syntax and they don't mix well in the same function. 一定要继续将其转换为async / await语法,但要注意async/await是一种替代语法,它们在同一函数中混合得不好。 As already stated by @Bergi , returning a new promise from an async function is an anti pattern - async functions return a promise already. 如@Bergi所述,从异步函数返回新的Promise是一种反模式-异步函数已经返回了Promise。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM