【问题标题】:How do I do a callback chain with q?如何使用 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();

这只会返回未定义...

【问题讨论】:

    标签: javascript asynchronous callback promise q


    【解决方案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,我在一些中型项目上成功使用了它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多