如何使用q实现回调链?

8
我在使用 JavaScript 的 promises 库“q”(https://github.com/kriskowal/q)时遇到了一些困难:
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个回答

12

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

对于setTimeout,Q已经提供了Q.delay(ms),它返回一个promise,该promise将在指定的毫秒数之后被解决,非常适合替换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


9
你得到"undefined"的原因是因为你链接的函数没有返回任何内容:
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,它会极大地提高我的代码质量,但另一方面它会导致硬依赖。你有这个问题的经验吗? - bodokaiser
1
如果您使用许多链接的异步调用,那么您将需要一些库来避免“毁灭金字塔” :). 我个人更喜欢asyncjs: https://github.com/caolan/async,并且我在一些中等规模的项目上成功地使用了它。 - wroniasty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接