Я читаю об отсрочках и обещаниях и постоянно сталкиваюсь с ними $.when.apply($, someArray)
. Я немного не понимаю, что именно он делает, ищу объяснение, что одна строка работает точно (а не весь фрагмент кода). Вот какой контекст:
var data = [1,2,3,4]; // the ids coming back from serviceA
var processItemsDeferred = [];
for(var i = 0; i < data.length; i++){
processItemsDeferred.push(processItem(data[i]));
}
$.when.apply($, processItemsDeferred).then(everythingDone);
function processItem(data) {
var dfd = $.Deferred();
console.log('called processItem');
//in the real world, this would probably make an AJAX call.
setTimeout(function() { dfd.resolve() }, 2000);
return dfd.promise();
}
function everythingDone(){
console.log('processed all items');
}
javascript
jquery
asynchronous
promise
маневрировать
источник
источник
.done()
можно использовать вместо.then
в этом случае, просто к вашему сведению_.when
поэтому вам не нужно его использоватьapply
.apply
: developer.mozilla.org/en-US/docs/JavaScript/Reference/… .Ответы:
.apply
используется для вызова функции с массивом аргументов. Он принимает каждый элемент массива и использует каждый в качестве параметра функции..apply
также может изменять context (this
) внутри функции.Итак, берем
$.when
. Говорят, что «когда все эти обещания исполнятся ... сделай что-нибудь». Требуется бесконечное (переменное) количество параметров.В вашем случае у вас есть множество обещаний; вы не знаете, сколько параметров вы передаете
$.when
. Передача самого массива в$.when
не сработает, потому что он ожидает, что его параметры будут обещаниями, а не массивом.Вот где
.apply
приходит на помощь. Он принимает массив и вызывает$.when
каждый элемент в качестве параметра (и проверяет,this
установлено ли значениеjQuery
/$
), так что все работает :-)источник
$.when
просто ожидает, пока все они будут завершены, прежде чем продолжить.$.when($, arrayOfPromises).done(...)
и$.when(null, arrayOfPromises).done(...)
(которые я нашел оба в качестве предлагаемых решений на форумах ...)$ .when принимает любое количество параметров и разрешается, когда все они разрешены.
anyFunction .apply (thisValue, arrayParameters) вызывает функцию anyFunction, устанавливающую ее контекст (thisValue будет this внутри этого вызова функции) и передает все объекты в arrayParameters как отдельные параметры.
Например:
Такой же как:
Но способ вызова apply позволяет вам передать массив с неизвестным количеством параметров. (В своем коде вы говорите, что данные поступают из службы, тогда это единственный способ вызвать $ .when )
источник
Здесь код полностью задокументирован.
источник
$.when.apply($, array)
это не то же самое , как$.when(array)
. Это то же самое, что:$.when(array[0], array[1], ...)
К сожалению, я не могу согласиться с вами, ребята.
Будет вызывать,
everythingDone
как только один deferred будет отклонен , даже если есть другие deferred'ы, которые ожидают рассмотрения .Вот полный сценарий (рекомендую http://jsfiddle.net/ ):
Это ошибка? Я хотел бы использовать это так, как описал выше господин.
источник
Может быть, кому-то это пригодится:
AllDone не вызывается в случае отклонения
источник
Только $ .when позволяет вызывать обратный вызов, когда все переданные ему обещания разрешаются / отклоняются. Обычно $ .when принимает переменное количество аргументов, использование .apply позволяет передать ему массив аргументов, это очень мощный инструмент. Для получения дополнительной информации о .apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply.
источник
Спасибо за элегантное решение:
Только один момент: при использовании
resolveWith
для получения некоторых параметров он прерывается из-за начального обещания, установленного на undefined. Что я сделал, чтобы все заработало:источник