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.