Как сериализовать массив функций Javascript, возвращающих обещания?
Мой вопрос очень похож на Этот , но я не могу заставить его работать : (
Задача:
-
У меня есть программа Javascript, которая должна работать в IE11 и Chrome.
-
В нем есть список функций, которые мне нужно выполнить по порядку.
-
Каждая функция возвращает обещание.
Promise.all(promisesArray)
работает до такой степени, что я могу "подождать", пока все функции закончатся, прежде чем продолжить. Но это не гарантирует, что каждая из функций будет выполняться порядок. Это имеет важное значение. -
Я пробовал использовать
Array.prototype.reduce()
, но я так и не смог понять, как им правильно пользоваться. -
Поскольку мне нужно работать в IE11, я не могу использовать функции ES6, такие как "функции стрелки".
Вот мой код:
<script>
var fn = function(arg) {
return new Promise (function (resolve, reject) {
console.log("fn(" + arg + ")...");
resolve("OK");
});
}
var p = fn("A").then(function(r) {
console.log("promise resolved: " + r + ".");
})
var chain = [];
chain.push(fn("3"));
chain.push(fn("1"));
chain.push(fn("2"));
console.log("Built chain:", chain);
Promise.all(chain);
chain.length = 0;
chain[2] = fn("30");
chain[1] = fn("20");
chain[0] = fn("10");
chain.reduce(function(promise, item) {
return promise.then(function() {
console.log("then:", item);
}), Promise.resolve();
});
console.log("Done.");
</script>;
Мне нужно, чтобы функции выполнялись по порядку array[0], array[1], array[2]
.
1 ответ:
Вы действительно близки со своим редуктором!
Начальным значением для редуктора являетсяPromise.resolve()
, поэтому при первом вызове функции:chain.reduce(function(promise, item) { // ^^ promise is a resolved promise, // ^^ item is chain[0] return promise.then(function() { console.log("then:", item); // ^^ when the promise resolves (immediately) this is called // BUT no value is returned. }), Promise.resolve();
});
Сравните это с ручным сцеплением обещаний. Вы бы вернули следующее обещание ждать:Promise.resolve() .then(item => { console.log("then: ", item); return fn("10"); }) .then(item => { console.log("then: ", item); return fn("20"); }) .then(item => { console.log("then: ", item); return fn("30"); })
Видите, как редуктор так близко? Мы просто хотим вернуть обещание:
var chain = [fn("10"), fn("20"), fn("30")]; chain.reduce(function(promise, item) { return promise.then(function() { console.log("then:", item); return item; }), Promise.resolve(); });
Edit:
Если вызовfn
запускает работу, каждое из этих назначений запускает вызовы не по порядку:chain.length = 0; chain[2] = fn("30"); chain[1] = fn("20"); chain[0] = fn("10");
Чтобы выполнить каждый
fn
в нужном порядке, вам придется отложить вызов доfn
, пока не разрешится предыдущий вызов. Мы сделали это в нашем примере руководства выше. В зависимости от сложности данных вы можете уменьшить массив аргументов дляfn
или обернуть каждый вызов в функцию, которая не будет выполняться:[10,20,30] .reduce(function(promise, arg) { return promise.then(function() { return fn(arg); }), Promise.resolve(); }); [function() { return fn(10); }, function() { return fn(20) }, function() { return fn(30) }] .reduce(function(promise, callFn) { return promise.then(function() { return fn(callFn); }), Promise.resolve(); });