2014-10-29 2 views
5

Я в процессе замены старого кода, который использовал объекты jQuery Deferred, и я переписываю с помощью Bluebird/ES6 Promises.Как запустить после того, как все javascript ES6 обещания разрешены

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

Использование JQuery Deferreds было бы что-то вроде этого:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests 
var promises = []; 
resuests.forEach(function(endpoint) { 
    promises.push($.ajax({url: endpoint})); 
}); 

$.when.apply($, promises).then(function() { 
    alert('all promises complete!'); 
}); 

Как переписать это с помощью синтаксиса ES6 Promise?

+1

С синтаксисом обещания JQuery, который может быть '$ .when.apply тогда (...' - много ($, requests.map ($ получить).). Очиститель –

ответ

5

Поскольку это помечено в дополнение к двум хороших решений вы уже получили здесь является более «Блюберд» путь:

var requests = [...]; 

Promise.map(requests, $.get).then(function(results){ 
    alert('all promises complete!'); 
}); 

Это, вероятно, так же просто, как и получается.

Как указывали другие, родной способ es6 должен был бы использовать Promise.all, no Promise.resolve или явное создание. Чистейший путь с носителями обещаний, вероятно, будет:

var requests = [...]; 
Promise.all(requests.map($.get)).then(function(results){ 

}); 
+0

Отличный ответ, и я ценю синтаксис Bluebird. В настоящее время я использую Bluebird, но могу придерживаться собственного синтаксиса, поскольку я могу рассмотреть возможность удаления Bluebird, когда ES6 официально поддерживается в основных браузерах. – dave

5

Использование Promise.all. Обратите внимание, что он принимает итерируемый, такой как массив в качестве аргумента, в отличие от $.when, поэтому не нужен .apply.

Вы также захотите преобразовать jQuery Deferred в родное обещание ES6, используя Promise.resolve(thejQueryDeferred). EDIT: Это делается неявно по вызову Promise.all, поэтому это действительно необязательно.

Всего код:

var requests = [...]; //some arbitrary data that is iterated to generate multiple ajax requests 
var promises = []; 
requests.forEach(function(endpoint) { 
    var nativePromise = Promise.resolve($.ajax({url: endpoint})); // if you want to make it clear that you're converting from jQuery Deferred to ES6 promise! 
    promises.push(nativePromise); 
}); 

Promise.all(promises).then(function() { 
    alert('all promises complete!'); 
}); 
+0

Спасибо, обновлено. Обратите внимание, что просто 'Promise.resolve (thejQueryDeferred)' достаточно, чтобы преобразовать jQuery Отложенное в Promise ES6 ('Promise.resolve' проверяет свойство' then' и действует соответственно). – Shai

+0

@dfsq на самом деле - Это настоящие обещания, построенные вокруг Promises/A +, которые, в свою очередь, построены таким образом, что возможны обещания jQuery. –

+0

Что касается комментария '.resolve' - вам на самом деле не нужно сделайте это, 'Promise.resolve' будет автоматически сделана для вас, когда нативные обещания будут потреблять иностранный' then'able. Вы можете видеть это i n spec (или даже MDN, с которым вы связаны). –

Смежные вопросы