Объединение обещаний с Q

В jquery я могу комбинировать обещания следующим образом:

var Promise = $.when(func1.execute(), func2.execute());
Promise.done(function (data1, data2) {
// code here
}

Как бы вы переписали это, используя Q?

Также. каковы преимущества использования Q в этом сценарии по сравнению с jquery?


person LastTribunal    schedule 19.04.2013    source источник


Ответы (2)


Простой ответ:

var promise = Q.all([func1.execute(), func2.execute()]);
promise.spread(function (data1, data2) {
  // code here
})
.done();

Аннотировано:

//make `promise` be a promise for the array
var promise = Q.all([func1.execute(), func2.execute()]);

//use spread to spread the array across the arguments of a function
promise.spread(function (data1, data2) {
  // code here
})
//use done so errors are thrown
.done();

Концепции в Q определены гораздо более четко. Обещание представляет собой единственное значение, которое может быть еще недоступно. Это очень точно соответствует синхронному коду.

Чтобы представить несколько значений, мы просто используем массив. Q.all — это вспомогательный метод, который принимает массив обещаний и возвращает обещание для массива, содержащего их выполненные значения. Если какое-либо обещание в массиве отклонено, результирующее обещание также будет отклонено.

Поскольку в этом случае мы точно знаем длину массива и, по сути, просто хотим элементы по отдельности, удобно использовать вспомогательную функцию spread, предоставленную Q. При вызове обещания для массива функция spread берет элементы массива и распределяет их по всем аргументам функции. Вы могли бы просто сделать:

//make `promise` be a promise for the array
var promise = Q.all([func1.execute(), func2.execute()]);
promise.done(function (data) {
  var data1 = data[0];
  var data2 = data[1];
  // code here
});

Это, возможно, концептуально проще, но значительно менее чисто. Я настоятельно рекомендую вам прочитать https://github.com/kriskowal/q/wiki/Coming-from-jQuery, так как это действительно полезный совет для тех, кто перешел из jQuery. Если вы найдете в нем что-то, что можно улучшить, вы можете отредактировать его и, надеюсь, помочь будущим людям сделать такой же переход.

person ForbesLindesay    schedule 22.04.2013
comment
Спасибо Форбс, это было именно то, что я искал! - person LastTribunal; 22.04.2013

В вопросе нет ничего, что нельзя было бы обнаружить после нескольких минут исследования, однако вот что:

Объединение обещаний

https://github.com/kriskowal/q/wiki/API-Reference#promise-for-array-methods

Сравнение Q и jQuery

Используйте jQuery или Q.Js для промисов

Хотя это далеко не универсальная истина, вы обнаружите, что Q предпочтительнее при программировании Node.js на стороне сервера, а jQuery предпочтительнее для использования на стороне клиента (в браузерах).

Если, как и я, вы пришли к Q, уже изучив jQuery, то вы найдете Q очень запутанным. В частности, утверждение из предложения Promises/A :

если обратный вызов выдает ошибку, возвращенное обещание будет переведено в состояние сбоя

интерпретируется образно в jQuery и буквально в Q. Следовательно, хотя Q делает акцент на выбрасывании/отлове ошибок (как в действительности, так и по аналогии в именовании некоторых своих методов), такого акцента, да и такого понятия, не существует в jQuery.

Вышеприведенное утверждение более формально выражено в разделе 3.2.4.6.2 предложения [Promises/A+], что приводит к модели отказа, которую (вместе с остальной частью раздела 3.2.4.6) вы сочтете полностью правильной или излишне негибкой. в зависимости от вашей точки зрения. Насколько я понимаю, Q соответствует разделу 3.2.4.6; jQuery нет.

person Beetroot-Beetroot    schedule 21.04.2013
comment
Спасибо за ваши несколько минут, но у меня до сих пор нет ответа, как переписать приведенное выше в Q. Мне нужно вернуть значения внутри .done(). Из документов Q неясно, как это сделать. .allResolved() и .all() кажутся верными, но не используют .done(). - person LastTribunal; 22.04.2013