jQuery 的延迟异步任务
Deferred Async Tasks with jQuery
我是 JavaScript 中延迟 类 的新手,我想实现一个循环遍历表单并逐个提交的函数。
看起来 Deferred 类 是实现此目的的方法。
我尝试遵循 this answer,但由于某种原因我的实施开始,等待 3 秒并完成。我希望它每 3 秒显示一个不同的表单名称,直到完成所有表单然后完成。
我做错了什么? JSFIDDLE
function syncAll() {
var promises = [];
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}];
$.each(forms, function (index, value) {
var def = new $.Deferred();
setTimeout(function () {
$("#output").html("Syncing: " + value.name);
def.resolve({ 'message': 'finito!' });
}, 3000);
promises.push(def);
});
return $.when.apply(undefined, promises).promise();
}
$.when(syncAll()).done(function(response){
$("#output").html(response.message);
});
/*
syncAll().done(function (response) {
$("#output").html(response.message);
}));
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">Start</div>
JSFiddle:https://jsfiddle.net/TrueBlueAussie/v6cgak1u/2/
这使用 promise = promise.then(functionReturningNextPromise)
模式:
function syncAll() {
var promise = $.when(); // Start with a resolved promise.
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}];
$.each(forms, function (index, value) {
promise = promise.then(function(){
var def = $.Deferred();
setTimeout(function () {
$("#output").html("Syncing: " + value.name);
def.resolve({ 'message': 'finito!' });
}, 3000);
return def.promise();
});
});
return promise;
}
$.when(syncAll()).done(function(response){
$("#output").html(response.message);
});
这可以通过替换 setTimeout 并使用定时承诺方法来改进,该方法也链接在一起(仍然使用 setTimeout 实现)。
请注意 new
不需要 $.Deferred()
编辑 :
可以利用 javascript 和 jQuery 的特性使代码稍微更简洁:
function syncAll() {
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}
];
return forms.reduce(function(promise, value) {
return promise.then(function() {
return $("#output").delay(1000).html("Syncing: " + value.name).promise();
});
}, $.when()).then(function() {
return {'message': 'finito!'};
});
}
syncAll().then(function(response) {
$("#output").html(response.message);
});
这与上面的范例基本相同,但利用了:
- 'array.reduce()' 从
forms
数组构建承诺链。
- jQuery的
.delay()
而不是setTimeout()
,实现延迟。
我是 JavaScript 中延迟 类 的新手,我想实现一个循环遍历表单并逐个提交的函数。
看起来 Deferred 类 是实现此目的的方法。
我尝试遵循 this answer,但由于某种原因我的实施开始,等待 3 秒并完成。我希望它每 3 秒显示一个不同的表单名称,直到完成所有表单然后完成。
我做错了什么? JSFIDDLE
function syncAll() {
var promises = [];
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}];
$.each(forms, function (index, value) {
var def = new $.Deferred();
setTimeout(function () {
$("#output").html("Syncing: " + value.name);
def.resolve({ 'message': 'finito!' });
}, 3000);
promises.push(def);
});
return $.when.apply(undefined, promises).promise();
}
$.when(syncAll()).done(function(response){
$("#output").html(response.message);
});
/*
syncAll().done(function (response) {
$("#output").html(response.message);
}));
*/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">Start</div>
JSFiddle:https://jsfiddle.net/TrueBlueAussie/v6cgak1u/2/
这使用 promise = promise.then(functionReturningNextPromise)
模式:
function syncAll() {
var promise = $.when(); // Start with a resolved promise.
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}];
$.each(forms, function (index, value) {
promise = promise.then(function(){
var def = $.Deferred();
setTimeout(function () {
$("#output").html("Syncing: " + value.name);
def.resolve({ 'message': 'finito!' });
}, 3000);
return def.promise();
});
});
return promise;
}
$.when(syncAll()).done(function(response){
$("#output").html(response.message);
});
这可以通过替换 setTimeout 并使用定时承诺方法来改进,该方法也链接在一起(仍然使用 setTimeout 实现)。
请注意 new
不需要 $.Deferred()
编辑 :
可以利用 javascript 和 jQuery 的特性使代码稍微更简洁:
function syncAll() {
var forms = [
{'name':'form 1'},
{'name':'form 2'},
{'name':'form 3'},
{'name':'form 4'}
];
return forms.reduce(function(promise, value) {
return promise.then(function() {
return $("#output").delay(1000).html("Syncing: " + value.name).promise();
});
}, $.when()).then(function() {
return {'message': 'finito!'};
});
}
syncAll().then(function(response) {
$("#output").html(response.message);
});
这与上面的范例基本相同,但利用了:
- 'array.reduce()' 从
forms
数组构建承诺链。 - jQuery的
.delay()
而不是setTimeout()
,实现延迟。