我想使用jquery的延迟/保证实现排队多个异步ajax请求:
function doSomething() {
console.log('doSomething')};
function makeMultiAjaxRequests1() {
console.log('makeMultiAjaxRequests1')};
function makeMultiAjaxRequests2() {
console.log('makeMultiAjaxRequests2')};
var step1 = function () {
var promise = new $.Deferred().promise();
makeMultiAjaxRequests1();
return promise; }
var step2 = function () {
var promise = new $.Deferred().promise();
makeMultiAjaxRequests2();
return promise; }
step1()
.then(step2())
.done(doSomething());
$.when(step1(),
step2())
.done(function () {
doSomething();
});
这是fiddle link。所以我的问题是:
在并行执行step1和step2的模式中,代码未到达最后一个处理函数。为什么呢?
答案 0 :(得分:8)
您需要在步骤1和步骤2中解析deferred
obj
试试这个
function doSomething() {
console.log('doSomething')};
function makeMultiAjaxRequests1(deferred) {
console.log('makeMultiAjaxRequests1')
deferred.resolve()};
function makeMultiAjaxRequests2(deferred) {
console.log('makeMultiAjaxRequests2')
deferred.resolve()};
var step1 = function () {
var deferred = new $.Deferred();
makeMultiAjaxRequests1(deferred);
return deferred; }
var step2 = function () {
var deferred = new $.Deferred();
makeMultiAjaxRequests2(deferred);
return deferred; }
step1().then(step2).done(doSomething);
$.when(step1(), step2()).done(function () {
doSomething();
});
答案 1 :(得分:4)
@Daiwei给出了一个很好的答案。
sergio-fry提到的一个常见要点是https://gist.github.com/sergio-fry/3917217。
如果你想要一个更加动态的方法,你事先不知道并行运行了多少个参数,这里是JQuery(1.10 +)的一个很好的示例扩展:
$.whenAll = function (deferreds) {
function isPromise(fn) {
return fn && typeof fn.then === 'function' &&
String($.Deferred().then) === String(fn.then);
}
var d = $.Deferred(),
keys = Object.keys(deferreds),
args = keys.map(function (k) {
return $.Deferred(function (d) {
var fn = deferreds[k];
(isPromise(fn) ? fn : $.Deferred(fn))
.done(d.resolve)
.fail(function (err) { d.reject(err, k); })
;
});
});
$.when.apply(this, args)
.done(function () {
var resObj = {},
resArgs = Array.prototype.slice.call(arguments);
resArgs.forEach(function (v, i) { resObj[keys[i]] = v; });
d.resolve(resObj);
})
.fail(d.reject);
return d;
};
请参阅动态实例中的代码:
答案 2 :(得分:0)
如果您为其提供了实际可以覆盖的网址,它确实会覆盖您的done
功能(如果是jsfiddle,则可以说是/echo/html/
:http://jsfiddle.net/LnaPt/2/
基本上,你只需要这样做:
var promise = $.ajax({
type: "GET",
url: "/echo/html/", //<-- instead of google
}).promise();