$ .when.apply($,someArray)做什么?
我正在阅读关于延期和承诺,并继续来$.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
。 这是用来说“当所有这些承诺解决…做一些事情”。 它需要一个无限的(可变)数量的参数。
就你而言,你有一系列的承诺; 你不知道有多lessparameter passing给$.when
。 将数组本身传递给$.when
将不起作用,因为它期望它的参数是promise,而不是数组。
这就是.apply
进来的地方。它需要数组,并且以每个元素作为参数调用$.when
(并确保将this
设置为jQuery
/ $
),这样就可以工作:-)
$ .when获取任何数量的参数,并解决所有这些都解决时。
anyFunction .apply(thisValue,arrayParameters)调用函数anyFunction设置其上下文(thisValue将是这个 )和arrayParameters中的所有参数。
例如:
$.when.apply($, [def1, def2])
是相同的:
$.when(def1, def2)
但是应用的调用方式允许您传递未知数量的参数数组。 (在你的代码中,你是说你的数据来自一个服务,那么这是调用$ .when的唯一方法)
在这里,代码完整logging。
// 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
。
下面是完整的脚本(我build议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'); }
这是一个错误? 我想用这个像上面描述的那位先生一样。
只有当每个承诺传递给它时,才能调用callback函数。 通常,$ .when需要可变数量的参数时,使用.apply可以将它传递给一个参数数组,它非常强大。 有关.apply的更多信息: https : //developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
感谢您的优雅解决scheme:
var promise; for(var i = 0; i < data.length; i++){ promise = $.when(promise, processItem(data[i])); } promise.then(everythingDone);
只要一点:当使用resolveWith
获取一些参数时,由于最初的promise被设置为undefined,它会中断。 我做了什么来使它工作:
// 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);
- AngularJS资源承诺
- 如何正确摆脱承诺链?
- Promise.all:parsing值的顺序
- 在AngularJS服务中caching承诺对象
- 推迟与承诺
- 为什么onRejected没有调用Promise.all()数组中包含的Promise.reject()传递给Promise.all()?
- Koa / Co / Bluebird或Q / Generators / Promises / Thunk相互影响? (Node.js)
- 延迟(),promise和Promise之间的区别
- 如何使用Bluebird对节点的child_process.exec和child_process.execFile函数进行promisify?