program story

$ .when.apply ($, someArray)는 무엇을합니까?

inputbox 2020. 8. 11. 08:25
반응형

$ .when.apply ($, someArray)는 무엇을합니까?


Deferreds과 약속에 대한 읽기 및 걸쳐 계속오고 $.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');
}

.apply인수 배열로 함수를 호출하는 데 사용됩니다. 배열의 각 요소를 취하고 각 요소를 함수에 대한 매개 변수로 사용합니다. 함수 내 .apply에서 컨텍스트 ( this)를 변경할 수도 있습니다 .

그래서 $.when. "이 모든 약속이 해결되면 ... 무언가를하라"는 말이 사용됩니다. 무한 (가변) 수의 매개 변수를 사용합니다.

귀하의 경우에는 일련의 약속이 있습니다. 얼마나 많은 매개 변수를 전달하는지 알 수 없습니다 $.when. 배열 자체를에 전달하는 $.when것은 매개 변수가 배열이 아니라 약속 일 것으로 예상하기 때문에 작동하지 않습니다.

그것이 .apply들어오는 입니다. 그것은 배열을 취하고 $.when각 요소를 매개 변수로 호출합니다 (그리고가 / this로 설정되어 있는지 확인하십시오 ). 그러면 모두 작동합니다 :-)jQuery$


$ .when 은 여러 매개 변수를 취하고 이러한 매개 변수 모두 해결 되면 해결됩니다.

anyFunction .apply (thisValue, arrayParameters)는 함수 호출 anyFunction 컨텍스트를 설정 (thisValue는 것 그 함수 호출 내)를 개별 파라미터로서 arrayParameters 모든 객체를 전달한다.

예를 들면 :

$.when.apply($, [def1, def2])

와 같다:

$.when(def1, def2)

그러나 apply 호출 방식을 사용하면 알 수없는 수의 매개 변수 배열을 전달할 수 있습니다. (귀하의 코드에서 데이터 는 서비스에서 제공되며 $ .when 을 호출하는 유일한 방법입니다 )


여기에 코드가 완전히 문서화되어 있습니다.

// 1. Declare an array of 4 elements
var data = [1,2,3,4]; // the ids coming back from serviceA
// 2. Declare an array of Deferred objects
var processItemsDeferred = [];

// 3. For each element of data, create a Deferred push push it to the array
for(var i = 0; i < data.length; i++){
  processItemsDeferred.push(processItem(data[i]));
}

// 4. WHEN ALL Deferred objects in the array are resolved THEN call the function
//    Note : same as $.when(processItemsDeferred[0], processItemsDeferred[1], ...).then(everythingDone);
$.when.apply($, processItemsDeferred).then(everythingDone); 

// 3.1. Function called by the loop to create a Deferred object (data is numeric)
function processItem(data) {
  // 3.1.1. Create the Deferred object and output some debug
  var dfd = $.Deferred();
  console.log('called processItem');

  // 3.1.2. After some timeout, resolve the current Deferred
  //in the real world, this would probably make an AJAX call.
  setTimeout(function() { dfd.resolve() }, 2000);    

  // 3.1.3. Return that Deferred (to be inserted into the array)
  return dfd.promise();
}

// 4.1. Function called when all deferred are resolved
function everythingDone(){
  // 4.1.1. Do some debug trace
  console.log('processed all items');
}

불행히도 나는 너희들과 동의 할 수 없다.

$.when.apply($, processItemsDeferred).always(everythingDone);

보류중인 다른 지연이 있더라도 everythingDone지연된 하나가 거부 되는 즉시 호출 합니다.

Heres the full script (I recommend http://jsfiddle.net/):

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

processItemsDeferred.push($.Deferred().reject());
//processItemsDeferred.push($.Deferred().resolve());

$.when.apply($, processItemsDeferred).always(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(){
  alert('processed all items');
}

It this a bug? I would like to use this like the gentleman above described it.


Maybe someone can find this useful:

$.when.apply($, processItemsDeferred).then(everythingDone).fail(noGood);

everythingDone isn't called in case of any reject


$.when alone makes it possible for a callback to be called when every promises passed to it are resolved/rejected. Normally, $.when takes a variable number of arguments, using .apply makes it possible to pass it an array of arguments, it's very powerful. For more info on .apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply


Thanks for your elegant solution:

var promise;

for(var i = 0; i < data.length; i++){
  promise = $.when(promise, processItem(data[i]));
}

promise.then(everythingDone);

Just one point: When using resolveWith to get some parameters, it breaks because of the initial promise set to undefined. What i did to make it work:

// Start with an empty resolved promise - undefined does the same thing!
var promise;

for(var i = 0; i < data.length; i++){
  if(i==0) promise = processItem(data[i]);
  else promise = $.when(promise, processItem(data[i]));
}

promise.then(everythingDone);

참고URL : https://stackoverflow.com/questions/14777031/what-does-when-apply-somearray-do

반응형