我有以下代码,其中d3.json
是异步函数。我试图在循环中运行它,而我的count
等于100.我的while
循环在第一次迭代后停止,因为count
发生在异步函数内,所以我不要经常多次运行它。如何获得正确的计数,以便我的while
循环在保持异步特征的同时继续执行?
$(document).ready(function() {
$('button').click(function() {
var start = new Date().getTime();
while(count == 100){
console.log("first iteration");
count = 0;
d3.json("/api/messages/" + offset, function(error, json) {
if (error) return console.warn(error);
data = json;
for(var i = 0; i < data.messages.length; i++){
console.log(data.messages[i].date);
count++;
console.log(count);
}
});
offset += 100;
}
var end = new Date().getTime();
var time = end - start;
console.log("Time to execute : " + time);
});
});
编辑:我正在尝试拨打电话,如下所示。在每次通话时,您都会检查并确保返回100项(计数),如果没有,您将停止while循环
/api/messages/0
/api/messages/100
/api/messages/200
/api/messages/300
/api/messages/400
/api/messages/500
/api/messages/600
答案 0 :(得分:2)
我将如何做到这一点:
创建一个接受相关参数的函数:start
offset,increment
,最重要的是应该在最后执行的done
回调。
此函数包含一个worker函数,它将调用API,检查结果并调用自身或done
回调:
function fetchAllMessages(start, increment, done) {
var messages = [];
(function nextCall(offset) {
d3.json("/api/messages/" + offset, function (error, data) {
if (error) return done(error, messages);
if (!data.messages) return done("unexpected response format", messages);
messages.push.apply(messages, data.messages);
if (data.messages.length === increment) {
nextCall(offset + increment);
} else {
done(null, messages);
}
});
})(start);
}
现在您只需从Click事件处理程序中使用它:
$(function() {
$('button').click(function() {
var start = Date.now();
fetchAllMessages(0, 100, function (err, messages) {
var end = Date.now();
if (err) console.warn(err);
console.log(messages);
console.log("Time to execute : " + (start - end));
});
});
});
答案 1 :(得分:1)
我们的想法是将此ajax
次调用链接起来,直到达到某个截止点(在此示例中,偏移量大于最大值)。
我已经将d3.json
调用更改为jQuery.getJSON
以获得此答案,因为它更容易在jsfiddle上调试,但概念完全相同。我还必须更改请求使用jsfiddle debug api的URL。
var start = new Date().getTime();
var offset = 0;
var maxOffset = 600;
var baseUrl = "/echo/json"; // change this to /api/messages in production
var callback = function(json) {
console.log(json);
console.log("current offset: " + offset);
data = json;
// ... do something with data ...
// increment the offset
offset += 100;
// don't run any more and return the execution time
if (offset > maxOffset) {
var end = new Date().getTime();
var time = end - start;
console.log("Time to execute : " + time);
return; // don't run any more
}
// offset too small so run another getJSON call with our callback
$.getJSON(baseUrl + "?" + offset, callback);
}
// when button is click, start the json call chain
$('button').click(function() {
// change the "?" to "/" in production
$.getJSON(baseUrl + "?" + offset, callback);
});
如果您需要帮助将此问题翻译成您确切的问题,请与我们联系。
Here是jsfiddle。