简体   繁体   中英

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. 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)

 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.

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

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.

First await does not permit .then or .catch methods to be called on the value it returns. The reason is that the value returned by await is never a promise. await only resumes execution after a successful promise operation and returns the result of the operation. 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 .

Promise Rejections

If the promise being waited on becomes rejected, the await operator throws the rejection reason without resuming function execution.

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. 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.

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. A single .catch clause on the outermost promise can be used to prevent uncaught promise rejections and notify that a failure occurred.

Conclusion

Try writing the code using plain promise chains if you are more familiar with that syntax. 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. As already stated by @Bergi , returning a new promise from an async function is an anti pattern - async functions return a promise already.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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