使用jQuery.Deferred来避免嵌套的setTimeout回调

时间:2013-08-01 00:32:46

标签: jquery coffeescript promise deferred

setTimeout ->
  console.log 'foo'
  setTimeout ->
    console.log 'bar'
    setTimeout ->
      console.log 'baz'
    , 1000
  , 1000
, 1000

是否可以使用jQuery.Deferred实现相同的结果?可能如下所示:

someFunction()
.then(-> console.log 'foo')
.then(delay 1000)
.then(-> console.log 'bar')
.then(delay 1000)
.then(-> console.log 'baz')

也许我认为承诺使写作变得容易:做A,然后一旦完成,做B,然后一旦完成,做C

2 个答案:

答案 0 :(得分:8)

您可以通过返回 .then()对象来链接Deferred来电。特别是对于延迟,你可以使用类似的东西:

function someFunction() {
    var ret = new $.Deferred();
    // setTimeout just to simulate `someFunction` taking 1000ms to complete its deferred
    setTimeout(function () {
        ret.resolve();
    }, 1000);
    return ret;
}

function logger(str) {
    return function () {
        console.log("Logger:", str);
    };
}

function delay(time) {
    return function () {
        console.log("Delaying");
        var ret = new $.Deferred();
        setTimeout(function () {
            ret.resolve();
        }, time);
        return ret;
    };
}

someFunction()
    .then(logger("foo"))
    .then(delay(3000))
    .then(logger("bar"))
    .then(delay(3000))
    .then(logger("baz"));

DEMO: http://jsfiddle.net/yGcfu/

答案 1 :(得分:1)

是的:

delay = (ms) -> ->
    d = $.Deferred()
    setTimeout d.resolve, ms
    d.promise()

demo at jsfiddle.net

或者,对于delay方法更常见,您省略了闭包(一个->)并使用

….then(-> delay 1000) …