Bluebird Promises: динамически создавать объект реквизита, но выполнять его параллельно.

Для данного примера здесь:

https://github.com/petkaantonov/bluebird/blob/master/API.md#props---promise

Promise.props({
    pictures: getPictures(),
    comments: getComments(),
    tweets: getTweets()
}).then(function(result) {
    console.log(result.tweets, result.pictures, result.comments);
});

Теперь, если я хочу создать объект реквизита динамически? Нравиться

var propObj = {};

if (cond1) {
    propObj.tweets = getTweets();
}
if (cond2) {
    propObj.pictures = getPictures();
}
if (cond3) {
    propObj.comments = getComments();
}

Promise.props(propObj)
.then(function(result) {
    console.log(result);
});

Приведенный выше код не будет работать должным образом. Функции getTweets, getPictures, getComments будут обязательно выполняться во время создания propsObj.

Однако на самом деле я ищу, чтобы выполнять эти функции параллельно во время фазы Promises.props(propObj), а затем возвращать объект результата. Есть ли способ сделать это?


person tapsboy    schedule 22.08.2015    source источник
comment
Что не так с их выполнением до Promises.props(propObj)? Все они возвращают обещания и будут поставлены в очередь и технически запущены параллельно. При назначении в строке Promises.props(propObj) они выполняются последовательно (чтобы вернуть обещание) во время построения объекта. Promises.props(propObj) просто ждет завершения всех свойств в propObj перед вызовом .then().   -  person Steven10172    schedule 23.08.2015
comment
Ваш пример работает идентично примеру кода Bluebird. В примере с Bluebird функции getPictures(), getComments() и getTweets() вызываются ДО того, как фактически вызывается Promise.props() — так же, как в вашем примере кода. То, что передается Promise.props(), является объектом, чьи свойства являются обещаниями. Начальная функция, сгенерировавшая промисы, уже вызвана, и операция уже запущена. Ваш код НЕ работает иначе, чем пример Bluebird. Не уверен, какую проблему вы пытаетесь решить.   -  person jfriend00    schedule 23.08.2015
comment
Вы, конечно, понимаете, что если ваши функции на самом деле являются просто синхронными вызовами функций, то в обычном Javascript нет такой вещи, как параллельная работа синхронных вызовов функций, потому что основной поток здесь однопоточный. Только одна вещь фактически выполняется за раз. Если операции являются асинхронными (например, сетевой или асинхронный файловый ввод-вывод), то после инициации вызова вы получаете некоторое фактическое параллельное действие, поскольку собственные библиотеки кода обрабатывают вещи в других потоках после возврата исходного вызова), но это не так. происходят для обычных синхронных вызовов функций.   -  person jfriend00    schedule 23.08.2015
comment
Вы можете избежать присваивания propObj, написав Promise.props({/* object literal */}).then(...);.   -  person Roamer-1888    schedule 23.08.2015
comment
@ Стивен10172 спасибо. Это прояснило мое понимание   -  person tapsboy    schedule 24.08.2015
comment
@jfriend00. Это имеет смысл. Я думал это неправильно. Кроме того, я думал о сетевом вводе-выводе, и, следовательно, все «параллельные» сомнения   -  person tapsboy    schedule 24.08.2015


Ответы (1)


Превращая мои комментарии в ответ, чтобы, возможно, завершить этот вопрос...

Ваш пример работает идентично примеру кода Bluebird. В примере с Bluebird функции getPictures(), getComments() и getTweets() вызываются ДО того, как действительно вызывается Promise.props() — так же, как в вашем примере кода. В Promise.props() передается объект, свойства которого являются промисами.

Итак, как в вашем примере, так и в примере с Bluebird происходит следующее:

  1. if (cond1), инициируйте getTweets() и назначьте полученное обещание propObj.tweets. Эта асинхронная операция продолжается в фоновом режиме.
  2. if (cond2), инициируйте getPictures() и назначьте полученное обещание propObj.pictures. Эта асинхронная операция продолжается в фоновом режиме.
  3. if (cond3), инициируйте getComments() и назначьте полученное обещание propObj.comments. Эта асинхронная операция продолжается в фоновом режиме.
  4. Вызовите promise.props(propObj), который просто перебирает свойства propObj, а затем ожидает вызова обработчика .then(), пока не будут выполнены все обещания, которые он находит.
  5. В конце концов все асинхронные операции завершаются и вызывается обработчик .then().

Начальная функция, сгенерировавшая промисы, уже вызвана, и операция уже запущена. Ваш код НЕ работает иначе, чем пример Bluebird. Не уверен, какую проблему вы пытаетесь решить.

Вы, конечно, понимаете, что если ваши функции на самом деле являются просто синхронными вызовами функций, то в обычном Javascript нет такой вещи, как параллельная работа синхронных вызовов функций, потому что основной поток здесь однопоточный. Только одна вещь фактически выполняется за раз. Если операции являются асинхронными (например, сетевой или асинхронный файловый ввод-вывод), то после инициации вызова вы получаете некоторое фактическое параллельное действие, поскольку собственные библиотеки кода обрабатывают вещи в других потоках после возврата исходного вызова), но это не так. происходят для обычных синхронных вызовов функций.

person jfriend00    schedule 23.08.2015
comment
Проблема в том, что они никогда не выполнят обещание и не вернут его. - person Steven10172; 23.08.2015
comment
@ Steven10172 - ответ переписан. - person jfriend00; 24.08.2015