我创建了以下javascript代码:
var index, _i;
var dfd = new $.Deferred();
dfd.resolve();
for (index = _i = 0; _i < 10; index = ++_i) {
$.when($, dfd).done(function() {
console.log('ping');
promise = (function(index) {
setTimeout(function() {
console.log('pong');
dfd.resolve();
}, 3000);
dfd.reject();
})(index);
})
}在控制台中,我看到以下结果
ping
ping
ping
ping
ping
ping
ping
ping
ping
ping
pong
pong
pong
pong
pong
pong
pong
pong
pong
pong但我想实现
ping
pong
ping
pong
....我错在哪里,如何根据我想要的行为重写代码?
发布于 2014-11-01 18:37:19
以下是一种方法:
function go(val, t) {
var def = $.Deferred();
setTimeout(function() {
log(val);
def.resolve();
}, t);
return def.promise();
}
function run(numCycles, values, delay) {
function next() {
if (numCycles > 0) {
go(values[0], delay).then(function() {
return go(values[1], delay);
}).then(function() {
--numCycles;
next();
});
}
}
next();
}
run(10, ["ping", "pong"], 500);工作演示:http://jsfiddle.net/jfriend00/g0Lxm3ws/
从概念上讲,这是如何工作的:
go()在计时器后输出一条消息。它返回消息输出后解析的承诺。run()接受多个循环和一个由两个值组成的数组来交替。next()检查是否还有更多的循环要运行,如果有,将两个go()操作链在一起,当最后一个操作完成时,减少循环的数量,然后再次调用next()。在您的实现中有各种各样的问题:
$.when()做了一系列的承诺,所以$.when($, dfd)错了。$.when(),因为您可以直接在承诺上使用.then()。for循环不会在承诺之间暂停,所以您的所有"ping"消息都会立即出来,然后"pong"消息会在稍后出现。FYI,如果您想循环一个任意的值数组,您可以这样做:
function go(val, t) {
var def = $.Deferred();
setTimeout(function() {
log(val);
def.resolve();
}, t);
return def.promise();
}
function run(numCycles, values, delay) {
function next() {
if (numCycles > 0) {
// create initial resolved promise
// for start of a .reduce() chain
var d = $.Deferred().resolve().promise();
values.reduce(function(p, val){
return p.then(function() {
return go(val, delay);
});
}, d).then(function() {
--numCycles;
next();
});
}
}
next();
}
run(5, ["tic", "tac", "toe"], 500);发布于 2014-11-01 17:56:31
我必须说,我不知道你是如何得到这类代码的,也不知道你真正想要实现的是什么。然而,至少要回答你的第一个问题(出了什么问题?):
https://stackoverflow.com/questions/26691226
复制相似问题