Bluebird обещава: Динамично изграждане на props обект, но изпълняван паралелно

За дадения пример тук:

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);
});

Сега, ако искам да изградя обекта props динамично? като

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, тъй като основната нишка тук е еднонишкова. Само едно нещо действително се изпълнява в даден момент. Ако операциите са асинхронни (напр. работа в мрежа или асинхронен файл I/O), тогава получавате някакво действително паралелно действие след стартиране на повикването, тъй като библиотеките с естествен код обработват неща в други нишки след връщането на първоначалното извикване), но това не се случи за редовни извиквания на синхронни функции.   -  person jfriend00    schedule 23.08.2015
comment
Можете да избегнете присвояването propObj, като напишете Promise.props({/* object literal */}).then(...);.   -  person Roamer-1888    schedule 23.08.2015
comment
@Steven10172 благодаря. Това изясни моето разбиране   -  person tapsboy    schedule 24.08.2015
comment
@jfriend00. Това има пълен смисъл. Мислех го неправилно. Също така имах в съзнанието си мрежов I/O и по този начин цялото съмнение за „паралелно изпълнение“.   -  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, тъй като основната нишка тук е еднонишкова. Само едно нещо действително се изпълнява в даден момент. Ако операциите са асинхронни (напр. работа в мрежа или асинхронен файл I/O), тогава получавате някакво действително паралелно действие след стартиране на повикването, тъй като библиотеките с естествен код обработват неща в други нишки след връщането на първоначалното извикване), но това не се случи за редовни извиквания на синхронни функции.

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