Вложенное обещание в обещание каждого

Может кто-нибудь объяснить, почему это не работает, как я ожидаю?

Я пытаюсь вернуть только идентификатор созданных или обновленных элементов для использования в Promise.each().then(). Это необходимо, потому что create возвращает объект и обновляет массив объектов.

Promise.each(items, function(item){
  if(...item doesn\'t exist...)
    return Item.create(item)
     .then(function (created) {
        return created.id;
        ///HOW DO I GET THIS ID ONLY?
      });
  else {
   return Item.update(item)
     .then(function (updated) {
        return updated[0].id;
        ///AND THIS ID?
      });
   }

}).then(function(result) {
  sails.log("THIS SHOULD BE AN ID" + JSON.stringify(result));
});

результатом является весь созданный объект, а не только идентификатор. Я хочу вернуть массив только обновленных идентификаторов. По-видимому, вложенные обещания - это плохо, но я не знаю, как это упростить.


person glasspill    schedule 10.02.2015    source источник
comment
Promise.each в версии 2.x возвращает исходный массив, а возврат внутри итератора служит только сигналом того, какое обещание ожидать перед итерацией следующего индекса. Что ты пытаешься сделать ? какой идентификатор вы пытаетесь вернуть и почему этот идентификатор?   -  person Esailija    schedule 10.02.2015
comment
так ты говоришь, что я не могу?   -  person glasspill    schedule 10.02.2015
comment
Я отредактировал свой вопрос, надеюсь, теперь понятно, что я хочу сделать   -  person glasspill    schedule 10.02.2015
comment
Я до сих пор не понимаю, а что, если будет создано много элементов? Какой идентификатор вы потом вернете и почему? Похоже, что несколько идентификаторов должны быть возвращены IE. массив - не идентификатор.   -  person Esailija    schedule 10.02.2015
comment
да, вы правы, я это и имел в виду. один идентификатор на элемент. Разве функция then() не вызывается один раз для каждого элемента в each()?   -  person glasspill    schedule 10.02.2015


Ответы (1)


Не используйте .each, используйте .map для сопоставления списка элементов со списком элементов:

Promise.map(items, function(item){
  if(...item doesn\'t exist...)
    return Item.create(item).get("id"); // get is a shortcut to .then(fn(x){ r x.id; })
  else {
   return Item.update(item).get(0).get(id);
}).then(function(result) {
  sails.log("Here is the array of all IDs + JSON.stringify(result));
});

Если вы хотите просмотреть их одну за другой и дождаться их, вы можете связать вторую .map. Если вы хотите, чтобы они выполнялись последовательно (намного медленнее) - .map также принимает параметр параллелизма.

Как сказал Эсаилия, в 3.0 поведение each изменяется, чтобы возвращать результаты, поэтому ваш исходный код был бы неэффективным, но на самом деле работал бы в 3.0.

person Benjamin Gruenbaum    schedule 10.02.2015
comment
Не знал о функции get. Это спасатель. Это прекрасно работает. Я бы дал тебе печенье, если бы мог - person glasspill; 10.02.2015