如何使用 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 进行回调链?的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode 两个数字相加 Q:如何从一个数字创建链表?