$ .when.apply($,someArray)做什么?

man*_*ire 105 javascript jquery asynchronous promise

我正在阅读Deferreds and Promises并继续发表$.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');
}
Run Code Online (Sandbox Code Playgroud)

Roc*_*mat 157

.apply用于调用带有参数数组的函数.它接受数组中的每个元素,并将每个元素用作函数的参数. .apply也可以更改this函数内的context().

那么,我们来看看吧$.when.它习惯于说"当所有这些承诺得到解决时......做点什么".它需要无限(可变)数量的参数.

在你的情况下,你有一系列的承诺; 你不知道你传递了多少参数$.when.传递数组本身是$.when行不通的,因为它希望它的参数是promises,而不是数组.

这就是它的位置.apply.它接受数组,并$.when使用每个元素作为参数进行调用(并确保将this其设置为jQuery/ $),因此一切正常:-)

  • @Darshan:你没有"跑"承诺.你等着他们解决.它们在创建时执行,`$ .when`等待所有它们在继续之前完成. (21认同)
  • 当多个promise被传递给$ .when方法时.他们将按什么顺序执行?一个接一个或并行? (3认同)
  • `$.when($, arrayOfPromises).done(...)` 和 `$.when(null, arrayOfPromises).done(...)` 之间的区别是什么(我在论坛...) (2认同)

小智 62

所有这些参数都已解决,$ .when会获取任意数量的参数并解析.

anyFunction .apply(thisValue,arrayParameters)调用函数anyFunction设置其上下文(thisValue将是该函数调用中的this)并将arrayParameters中的所有对象作为单独的参数传递.

例如:

$.when.apply($, [def1, def2])
Run Code Online (Sandbox Code Playgroud)

是相同的:

$.when(def1, def2)
Run Code Online (Sandbox Code Playgroud)

但是应用调用方式允许您传递一组包含未知数量的参数.(在你的代码中,你说你的数据来自一个服务,那么这是调用$ .when的唯一方法)


Yan*_*hon 14

在这里,代码完整记录.

// 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');
}
Run Code Online (Sandbox Code Playgroud)

  • `$ .when.apply($,array)`与*.when(array)`的*不相同.它与:`$ .when(array [0],array [1],...)`相同 (7认同)