jQuery.Deferred(function() {...}) 在调用 $.when(...) 之前执行
jQuery.Deferred(function() {...}) executing before I call $.when(...)
我有数量可变的 $.Deferred()
个对象,它们被推入数组以通过 $.when()
执行。根据 elsewhere on Stack Overflow 的建议,我决定采用手工编码的 $.when.all([$.Deferred(), ...])
方法。
具体来说,$.Deferred()
对象包含一个函数,每个对象执行一个 indexedDB .put()
。我希望它们在调用 $.when.all()
时完成,并在其对应的 .then()
函数中执行代码,但我通过断点发现它在调用它时立即执行 .put()
,并执行javascript 一起绕过 .then()
函数并继续。
var putQueryArray = [];
_.each(favorites, function(fav) { // favorites being an array of updated indexedDB .get()s
var objectStore = db.transaction(['store'], 'readwrite') // var db defined elsewhere
.objectStore('store');
putQueryArray.push($.Deferred(function() {
var update = objectStore.put(fav); // This executes immediately, as verified in Chrome's Resources tab
update.onsuccess = _.bind(function(e) {
this.resolve(e); // Even if I put a breakpoint here, it never triggers
}, this);
update.onerror = _.bind(function(e) {
this.reject(e);
}, this);
}).promise());
});
// It appears this is ignored all together
$.when.all(putQueryArray).then(function(res) { // I (think I) expect this line to execute the above array of $.Deferred()'s?
//This function never executes
}, function(err) { ... });
我已经尝试了所有方法,从不将整个函数包装在 $.Deferred(function() { ... });
中,而是将 $.Deferred 作为函数中的变量调用并返回它的承诺,到一起排除 .promise()
部分,两者都会导致它实际执行 .then()
函数,但不会实际执行 .put()
。我在上面的代码中做错了什么?
answer where you discovered jQuery.when.all()
在使用之前定义了该方法。换句话说,jQuery.when.all()
是自定义的,而不是本机的 jQuery 方法。
它旨在克服 jQuery.when()
易于理解和容忍的问题,即它只接受离散的承诺作为参数,而不是一系列承诺。
这不是一个大问题的原因是因为 javascript 的原生 Function.prototype.apply 允许使用参数数组来调用任何函数而不是离散参数(对于 thisArg
待定)。
事实上,如果您通读发现自定义方法的答案,那么您会发现这正是它为您所做的。
完整的,不使用 jQuery.when.all()
,你会写:
$.when.apply(null, putQueryArray).then(function(res) {
...
}, function(err) {
...
});
许多人选择写 $.when.apply($, putQueryArray)
,尽管第一个参数 thisArg
没有被 $.when
使用,null
就足够了。
了解所有内容并 $.when.all()
安全安装(很可能是这种情况),然后您可以开始查看其他代码。
罪魁祸首似乎是延迟的方式 resolved/rejected。
尝试:
putQueryArray.push($.Deferred(function(dfrd) { // `dfrd` is a reference to the Deferred that will be returned
var update = objectStore.put(fav);
// `dfrd.resolve` and `dfrd.reject` both have `dfrd` already bound in, so .bind() is not required.
update.onsuccess = dfrd.resolve;
update.onerror = dfrd.reject;
}).promise());
如果你还有问题,那么可能objectStore.put()
并没有按照你想的那样工作,或者只是错误期望的问题。
I would expect them to complete upon calling $.when.all(), and execute code within it's corresponding .then() function, yet I discovered via breakpoints that it immediately executes the .put() upon invoking it, ...
传递给jQuery.Deferred()
的函数是同步执行的,所以objectStore.put(fav);
确实会立即执行。目前尚不清楚您可能想要什么替代行为。
我有数量可变的 $.Deferred()
个对象,它们被推入数组以通过 $.when()
执行。根据 elsewhere on Stack Overflow 的建议,我决定采用手工编码的 $.when.all([$.Deferred(), ...])
方法。
具体来说,$.Deferred()
对象包含一个函数,每个对象执行一个 indexedDB .put()
。我希望它们在调用 $.when.all()
时完成,并在其对应的 .then()
函数中执行代码,但我通过断点发现它在调用它时立即执行 .put()
,并执行javascript 一起绕过 .then()
函数并继续。
var putQueryArray = [];
_.each(favorites, function(fav) { // favorites being an array of updated indexedDB .get()s
var objectStore = db.transaction(['store'], 'readwrite') // var db defined elsewhere
.objectStore('store');
putQueryArray.push($.Deferred(function() {
var update = objectStore.put(fav); // This executes immediately, as verified in Chrome's Resources tab
update.onsuccess = _.bind(function(e) {
this.resolve(e); // Even if I put a breakpoint here, it never triggers
}, this);
update.onerror = _.bind(function(e) {
this.reject(e);
}, this);
}).promise());
});
// It appears this is ignored all together
$.when.all(putQueryArray).then(function(res) { // I (think I) expect this line to execute the above array of $.Deferred()'s?
//This function never executes
}, function(err) { ... });
我已经尝试了所有方法,从不将整个函数包装在 $.Deferred(function() { ... });
中,而是将 $.Deferred 作为函数中的变量调用并返回它的承诺,到一起排除 .promise()
部分,两者都会导致它实际执行 .then()
函数,但不会实际执行 .put()
。我在上面的代码中做错了什么?
answer where you discovered jQuery.when.all()
在使用之前定义了该方法。换句话说,jQuery.when.all()
是自定义的,而不是本机的 jQuery 方法。
它旨在克服 jQuery.when()
易于理解和容忍的问题,即它只接受离散的承诺作为参数,而不是一系列承诺。
这不是一个大问题的原因是因为 javascript 的原生 Function.prototype.apply 允许使用参数数组来调用任何函数而不是离散参数(对于 thisArg
待定)。
事实上,如果您通读发现自定义方法的答案,那么您会发现这正是它为您所做的。
完整的,不使用 jQuery.when.all()
,你会写:
$.when.apply(null, putQueryArray).then(function(res) {
...
}, function(err) {
...
});
许多人选择写 $.when.apply($, putQueryArray)
,尽管第一个参数 thisArg
没有被 $.when
使用,null
就足够了。
了解所有内容并 $.when.all()
安全安装(很可能是这种情况),然后您可以开始查看其他代码。
罪魁祸首似乎是延迟的方式 resolved/rejected。
尝试:
putQueryArray.push($.Deferred(function(dfrd) { // `dfrd` is a reference to the Deferred that will be returned
var update = objectStore.put(fav);
// `dfrd.resolve` and `dfrd.reject` both have `dfrd` already bound in, so .bind() is not required.
update.onsuccess = dfrd.resolve;
update.onerror = dfrd.reject;
}).promise());
如果你还有问题,那么可能objectStore.put()
并没有按照你想的那样工作,或者只是错误期望的问题。
I would expect them to complete upon calling $.when.all(), and execute code within it's corresponding .then() function, yet I discovered via breakpoints that it immediately executes the .put() upon invoking it, ...
传递给jQuery.Deferred()
的函数是同步执行的,所以objectStore.put(fav);
确实会立即执行。目前尚不清楚您可能想要什么替代行为。