如何使用q进行回调链?

时间:2012-09-17 14:36:52

标签: javascript asynchronous callback promise q

我在理解如何使用" 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();

这只返回undefined ......

2 个答案:

答案 0 :(得分:12)

正如wroniasty指出的那样,你需要从每个函数中返回一个promise,但你也应该尽可能抽象出任何面向回调的API(比如setTimeout),并使用返回promises的API。 / p>

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

答案 1 :(得分:9)

您获得“未定义”的原因是因为您链接的函数没有返回任何内容:

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/