Как мне сериализовать массив функций Javascript, возвращающих обещания? - PullRequest
0 голосов
/ 10 мая 2018

Мой вопрос очень похож на это , но я не могу заставить его работать: (

ПРОБЛЕМА:

  1. У меня есть программа Javascript, которая должна работать в IE11 и Chrome.

  2. В нем есть список функций, которые мне нужно выполнить по порядку.

  3. Каждая функция возвращает Обещание. Promise.all(promisesArray) работает до такой степени, что я могу «ждать», пока все функции не завершатся, прежде чем продолжить. Но это НЕ гарантирует, что каждая из функций работает по порядку. Это важно.

  4. Я пытался использовать Array.prototype.reduce(), но я не смог понять, как правильно его использовать.

  5. Поскольку мне нужно работать в 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 Ответ

0 голосов
/ 10 мая 2018

Вы действительно близки со своим редуктором!

Начальное значение для редуктора: 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();
});

Редактировать :
Если вызов 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();
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...