我有一个简单的服务方法,收集了几个.get()
,我在"打印"上遇到了一些麻烦。从那时起,我只有一部分结果。
var service = function() {
var players = []; // will hold 100 objects
var getMembers = function(id) {
$.get(url, function(data) {
for(i=0; i<data.length; i++) {
var p = data[i];
// get more info for this member
getMemberDetails(p.member_id);
// put the current data into the players
players.push(p);
}
});
calculateAndPrint();
};
var getMemberDetails = function(id) {
$.get(url, function(data) {
var result = $.grep(players, function(e){ return e.member_id == id; });
if (result.length == 0) { /* not found */ }
else if (result.length == 1) {
// push new data to player object
result[0].details = data;
}
});
};
var calculateAndPrint = function() {
for(i=0; i<players.length; i++) {
var p = players[i];
console.log(p);
}
};
})();
这不起作用,因为当我到达calculateAndPrint
时,details
甚至还没有设计......
所以我尝试了$.Deferred()
,我唯一的问题是,如果我推迟getMemberDetails
方法,那个电话已经包含了一个deffer call(.get()
)和I&I #39;回到同一个问题......
在完成所有100次调用后,仅运行calculateAndPrint
的最佳选择是什么?
这似乎很容易,但我只是空白:/
答案 0 :(得分:3)
如果你使用promises,这应该很容易:
var service = function() {
var getMembers = function(id) {
return Promise.when($.get("some service url"))
.then(function (data) {
return Promise.all(data.map(getMemberDetails));
});
};
var getMemberDetails = function(player) {
return Promise.when($.get("some service Url?id=" + player.member_id));
};
var calculateAndPrint = function(players) {
players.forEach(function (player) {
console.log(player);
});
};
return {
getMembers: getMembers,
calculateAndPrint: calculateAndPrint
};
})();
service.getMembers().then(function (players) {
service.calculateAndPrint(players);
});
答案 1 :(得分:-1)
你可以为你制作的每个ajax调用创建一个延迟对象$.deferred
。然后等待($.when
)在运行calculateAndPrint()
方法之前完成所有延期作业。
工作原理:
$.deferred
&amp;返回promise对象.promise()
。.resolve(responseData)
解析或拒绝错误数据.reject(errorData)
。calculateAndPrint()
方法。deferredCalls
数组。注意:我建议你在进行ajax调用时显示一些loader / spinner图像,因为你不会立即得到响应&amp;让用户了解后台操作总是很好的用户体验标志。
JS CODE:
/* utils */
var $ul = $('ul');
function msg(text) {
$ul.append('<li>' + text + '</li>');
}
/* functions */
function asyncThing1() {
var dfd = $.Deferred();
setTimeout(function() {
msg('asyncThing1 seems to be done...');
dfd.resolve('banana');
}, 1000);
return dfd.promise();
}
function asyncThing2() {
var dfd = $.Deferred();
setTimeout(function() {
msg('asyncThing2 seems to be done...');
dfd.resolve('apple');
}, 500);
return dfd.promise();
}
function asyncThing3() {
var dfd = $.Deferred();
setTimeout(function() {
msg('asyncThing3 seems to be done...');
dfd.resolve('orange');
}, 1500);
return dfd.promise();
}
/* do it */
$.when(asyncThing1(), asyncThing2(), asyncThing3()).done(function(res1, res2, res3) {
msg('all done!');
msg(res1 + ', ' + res2 + ', ' + res3);
});
任意延期电话Original SO Post:
//Push all arbitrary ajax calls to deferred array
var deferreds = [];
function getSomeDeferredStuff() {
var i = 1;
for (i = 1; i <= 10; i++) {
var count = i;
deferreds.push(
$.post('/echo/html/', {
html: "<p>Task #" + count + " complete.",
delay: count
}).success(function(data) {
$("div").append(data);
}));
}
}
// define a extension method for $.when for creating/managing deferred
// objects for every ajax call
if (jQuery.when.all===undefined) {
jQuery.when.all = function(deferreds) {
var deferred = new jQuery.Deferred();
$.when.apply(jQuery, deferreds).then(
function() {
var deferredObjs= function (arguments) { return deferreds.length > 1 ? $.makeArray(arguments) : [arguments]; }
deferred.resolve(deferredObjs);
},
function() {
deferred.fail(deferredObjs);
});
return deferred;
}
}
//passing the deferred calls array to $.when
$.when.all(deferreds).then(function(objects) {
//process when all deferred objects compelted
console.log("Resolved/rejected objects:", objects);
});