This question already has an answer here:
- Using async/await with a forEach loop 15 answers
Given the following code
class SomeClass {
async someFunc() {
const urlParameters = [0, 1, 2];
const batchAjaxResult = await urlParameters.map((parameter) => {
const result = await $.get(`someUrl/${parameter}`);
return {
parameter,
result
}
});
console.log(batchAjaxResult);
}
}
JavaScript will return an Array of resolved Promises instead of the actual Promises result.
This is probably due to Array.map() not being implemented as a Promise.
Is there a Promise-based version of Array.map?
This is question differs from How to return the response from an asynchronous call, because it's about How to return batched responses wrapped inside Array.map.
You could use this simple function which chains the promises to achieve sequential execution:
function asyncMap(arr, mapper) {
var q = Promise.resolve();
return Promise.all(arr.map(v => q = q.then(() => mapper(v))));
}
// Usage
asyncMap([1, 2, 3], v => {
return new Promise(resolve => {
console.log("Start " + v);
setTimeout(() => {
console.log("End " + v);
resolve("foo" + v);
}, 500);
});
}).then(a => console.log(a));
By writing this question I managed to get down to the root of the problem.
It seems like Bluebird has such an feature called Promise.map
Similarily there is a native implementation called Promise.all that creates a "bulk Promise"
I changed the code as follows and it's working:
class SomeClass {
async someFunc() {
const urlParameters = [0, 1, 2];
const batchAjaxResult = await Promise.all(
urlParameters.map(async (parameter) => {
const result = await $.get(`someUrl/${parameter}`);
return {
parameter,
result
}
})
);
console.log(batchAjaxResult);
}
}
来源:https://stackoverflow.com/questions/38694958/javascript-async-await-for-promises-inside-array-map