This question already has answers here:
Closed 3 years ago.
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);
}
}