Как запустить цепочку обещаний, затем использовать карту или уменьшить произвольное количество элементов цепочки?

Я застрял на следующем:

Скрипт возвращает произвольное число n или массив, например:

[["a"], ["b"], ["c"], ["d"]]

Мне нужно перебрать массивы, используя обещание then(), но, поскольку я не знаю, сколько элементов будет, я сделал это:

  var bundle_list = [["a"], ["b"], ["c"], ["d"]];

  var x = bundle_list.reduce(function(current, next) {
  console.log(current);

  // requestBundle will also return a promise
  return requestBundle(current)
    .then(function(bundle_response) {
      // do foo
      console.log("CALLING NEXT")
      console.log(next);
      return RSVP.resolve(next);
    });
})

x.then(function(last_response) {
  return console.log("DONE")
});

Моя проблема в том, что мои reduce/map запускают все итерации до запуска моего асинхронного кода, поэтому я получаю 3-кратную консоль current, за которой следует консоль done. Таким образом, весь мой «цикл» на карте запускается мгновенно, а результаты появляются немного (слишком) позже...

Я использую эту реализацию RSVP, но это A+, поэтому проблем быть не должно. Я пытался работать с предоставленным ответом здесь, но я не могу заставить его работать должным образом.

Вопрос:
Можно ли создать "затем-цепочку" с произвольным количеством операторов then. Если это так, некоторые указатели приветствуются!

Спасибо!


person frequent    schedule 04.05.2014    source источник


Ответы (1)


Цикл for (или forEach) должен выполнять:

var queue = RSVP.Promise.resolve(); // in ES6 or BB, just Promise.resolve();

bundle_list.forEach(function(el){
    queue = queue.then(function(res){
        console.log("Calling async func for", el);
        return requestBundle(el);
    });
});

queue.then(function(lastResponse){
    console.log("Done!");
});
person Benjamin Gruenbaum    schedule 04.05.2014
comment
отлично. Даже не подумал о forEach... Работает как шарм. - person frequent; 04.05.2014
comment
вы можете добавить, что для вызова запроса следующим образом: request(["foo", "bar"]).then(function(module_arr) {...}) последняя часть очереди также должна возвращать RSVP.resolve. - person frequent; 04.05.2014
comment
Идеальный ответ! Мне нужно это для смешанных запросов firebase, и это работает потрясающе. - person the_bluescreen; 03.01.2017