如何使用 q 进行回调链?

Posted

技术标签:

【中文标题】如何使用 q 进行回调链?【英文标题】:How do I do a callback chain with q? 【发布时间】:2012-09-09 19:21:52 【问题描述】:

我在理解如何使用 "q" (https://github.com/kriskowal/q) 一个用于 javascript 的承诺库时遇到了一些问题:

var delayOne = function() 
    setTimeout(function() 
        return 'hi';
    , 100);
;

var delayTwo = function(preValue) 
    setTimeout(function() 
        return preValue + ' my name';
    , 200);
;

var delayThree = function(preValue) 
    setTimeout(function() 
        return preValue + ' is bodo';
    , 300);
;

var delayFour = function(preValue) 
    setTimeout(function() 
        console.log(preValue);
    , 400);

;

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).end();

这只会返回未定义...

【问题讨论】:

【参考方案1】:

正如 wroniasty 指出的那样,您需要从每个函数返回一个 Promise,但您还应该尽可能抽象任何面向回调的 API(如 setTimeout)并使用返回 Promise 的 API。

setTimeout 的情况下,Q 已经提供了Q.delay(ms),它返回一个承诺,该承诺将在指定的毫秒数后解决,非常适合替换setTimeout

var delayOne = function() 
    return Q.delay(100).then(function() 
        return 'hi';
    );
;

var delayTwo = function(preValue) 
    return Q.delay(200).then(function() 
        return preValue + ' my name';
    );
;

var delayThree = function(preValue) 
    return Q.delay(300).then(function() 
        return preValue + ' is bodo';
    );
;

var delayFour = function(preValue) 
    return Q.delay(400).then(function() 
        console.log(preValue);
    );
;

Q.fcall(delayOne).then(delayTwo).then(delayThree).then(delayFour).done();

(注意:end 已替换为 done

【讨论】:

【参考方案2】:

你得到“未定义”的原因是因为你链接的函数没有返回任何东西:

var delayOne = function() 
  setTimeout(function() 
    return 'hi';
  , 100);
;

delayOne 调用 setTimeout,但什么也不返回 (undefined)。

要实现您的目标,您必须使用Q.defer

var delayOne = function() 
  var d = Q.defer();    
  setTimeout(function() 
    d.resolve("HELLO");
  , 100);
  return d.promise;
;

var delayTwo = function(preValue) 
   setTimeout(function() 
     alert(preValue);
   , 
   400);
;

delayOne().then ( delayTwo );

http://jsfiddle.net/uzJrs/2/

【讨论】:

感谢您的解决方案。除此之外,我必须做出决定,如果我使用 Q 会大大提高我的代码质量,另一方面会导致硬依赖。遇到这个问题你有经验吗? 如果您使用许多链式异步调用,那么您将需要一些库来逃避“末日金字塔”:)。我个人更喜欢 asyncjs:github.com/caolan/async,我在一些中型项目上成功使用了它。

以上是关于如何使用 q 进行回调链?的主要内容,如果未能解决你的问题,请参考以下文章

C语言链表中如何实现对一组数据进行排序?

如何编写测试用例来覆盖承诺链中所有嵌套的“then”回调

Leetcode 两个数字相加 Q:如何从一个数字创建链表?

扭曲的延迟/回调和异步执行

区块链学姐:6月13日短暂反弹下再次走出回调,后续方向如何看待?

区块链学姐:9月13日 主流币再度回调之下,后续主力该如何选择?