首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >乒乓球行为

问乒乓球行为
EN

Stack Overflow用户
提问于 2014-11-01 17:11:33
回答 2查看 176关注 0票数 1

我创建了以下javascript代码:

代码语言: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);
  })  
}

在控制台中,我看到以下结果

代码语言:javascript
复制
ping
ping
ping
ping
ping
ping
ping
ping
ping
ping
pong
pong
pong
pong
pong
pong
pong
pong
pong
pong

但我想实现

代码语言:javascript
复制
ping
pong
ping
pong
....

我错在哪里,如何根据我想要的行为重写代码?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-01 18:37:19

以下是一种方法:

代码语言:javascript
复制
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/

从概念上讲,这是如何工作的:

  1. 函数go()在计时器后输出一条消息。它返回消息输出后解析的承诺。
  2. 函数run()接受多个循环和一个由两个值组成的数组来交替。
  3. 函数next()检查是否还有更多的循环要运行,如果有,将两个go()操作链在一起,当最后一个操作完成时,减少循环的数量,然后再次调用next()。

在您的实现中有各种各样的问题:

  1. 一个特定的延迟或承诺只能被解决或拒绝一次。
  2. $.when()做了一系列的承诺,所以$.when($, dfd)错了。
  3. 当只有一个承诺时,甚至不需要$.when(),因为您可以直接在承诺上使用.then()。
  4. 您的for循环不会在承诺之间暂停,所以您的所有"ping"消息都会立即出来,然后"pong"消息会在稍后出现。

FYI,如果您想循环一个任意的值数组,您可以这样做:

代码语言:javascript
复制
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);

工作演示:http://jsfiddle.net/jfriend00/1ckb6sg6/

票数 2
EN

Stack Overflow用户

发布于 2014-11-01 17:56:31

我必须说,我不知道你是如何得到这类代码的,也不知道你真正想要实现的是什么。然而,至少要回答你的第一个问题(出了什么问题?):

  • 一旦推迟解决,它就不能(我相信)以后被拒绝。正如this question中所讨论的,它们是作为一次性使用对象的.
  • 其次,在pongs之前得到所有的pings,因为输出pings的机制是同步的(循环)。然而,乒乓输出的机制是异步的--超时。因此,实际上,pings都是在同一个过程实例中输出的,而pongs直到3秒后才会启动--在pings被输出很久之后。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26691226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档