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

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。

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

 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")); 

演示: http //jsfiddle.net/yGcfu/

是的:

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

( 在jsfiddle.net演示 )

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

 ….then(-> delay 1000) …