In a Node app, I need to iterate through some items in a synchronous fashion, but some of the operations inside the loop are asynchronous. My code right now looks like so:>
You should be able to remove .forEach()
; use Array.prototype.reduce()
to return an array of Promise
values to Promise.all()
. If element with items
is a function, call function, else wrap within Promise.resolve()
, which should return results in same order as in items
array
See Promise.all()
Promise.all
passes an array of values from all the promises in the iterable object that it was passed. The array of values maintains the order of the original iterable object, not the order that the promises were resolved in. If something passed in the iterable array is not a promise, it's converted to one by Promise.resolve.
var arr = [1, // not asynchronous
function j() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(2)
}, Math.floor(Math.random() * 10000))
})
}, // asynchronous
3, // not asynchronous
function j() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(4)
}, Math.floor(Math.random() * 3500))
})
}, // asynchronous
5, // not asynchronous
Promise.resolve(6), // asynchronous
7
];
Promise.all(arr.reduce(function(p, next) {
var curr = Promise.resolve(typeof next === "function" ? next() : next);
return p.concat.apply(p, [curr.then(function(data) {
console.log(data);
return data
})]);
}, []))
.then(function(data) {
console.log("complete", data)
})
An alternative approach would be to use Array.prototype.shift()
, Promise.resolve()
, .then()
, recursion
function re(items, res) {
if (items.length) {
var curr = items.shift();
return Promise.resolve(
typeof curr === "function"
? curr()
: curr
).then(function(data) {
// values from `arr` elements should be logged in sequential order
console.log(data);
res.push(data)
}).then(re.bind(null, items, res))
} else {
return ["complete", res]
}
}
var _items = arr.slice(0);
re(_items, [])
.then(function(complete) {
console.log(complete)
})
var arr = [1, // not asynchronous
function j() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(2)
}, Math.floor(Math.random() * 10000))
})
}, // asynchronous
3, // not asynchronous
function j() {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(4)
}, Math.floor(Math.random() * 3500))
})
}, // asynchronous
5, // not asynchronous
Promise.resolve(6), // asynchronous
7
];
function re(items, res) {
if (items.length) {
var curr = items.shift();
return Promise.resolve(
typeof curr === "function"
? curr()
: curr
).then(function(data) {
// values from `arr` elements should be logged in sequential order
console.log(data);
res.push(data)
}).then(re.bind(null, items, res))
} else {
return ["complete", res]
}
}
var _items = arr.slice(0);
re(_items, [])
.then(function(complete) {
console.log(complete)
})