有点困惑q和nodejs承诺
我目前在nodejs中有几个js文件,它们是作为模块加载的,并且增加了app对象(使用express)。
所以他们的签名看起来像:
module.exports = function(app, callback) { // ... callback(); }
所以目前我有大约5个我的代码看起来像:
require("./setup/a")(app, function() { require("./setup/b")(app, function(){ require("./setup/c")(app, function(){ require("./setup/d")(app, function(){ require("./setup/e")(app, function(){ startApp(); }) }) }) }) });
现在,它看起来不好看,因为它的“厄运的金字塔”,但是我不完全确定如何改变这种模式来使用Q,因为我假设我会使用Q.fcall(...a).then(...b).etc.done()
。 然而,我不确定我是如何将应用程序传递给它的,如果我需要返回它的callback以作为承诺来处理。
理想情况下,我不想通过我的代码开始重新启动Q我只希望它在我想删除金字塔用例的地方,所以在上面的例子中,我如何使用Q来承诺将应用程序传递到每个需要的模块然后在最后启动应用程序?
假设你的模块没有使用promise,你可以这样做:
module.exports = function(app) { // do some stuff with app return new Promise(function(resolve,reject){ // when ready to resolve after some actions on app resolve(); // you can also return a value here as a cb param }); }; Promise.all(["./setup/a","./setup/b","./setup/c"].map(require.bind(null,app))) .then(startApp);
但是,您应该尽可能使用承诺,这意味着您可以简单地返回您在过程中使用的承诺:
module.exports = function(app){ return something(app).then(function(){ return somethingElseAsyncWithApp(app); }); };
所以promise构造函数不是必需的。 请注意,这个答案使用原生承诺,但也可以在像Bluebird这样的语法库上使用。 对于Q将new Promise
改为new Q.Promise
和Promise.all
以Q.all
。
或者,您可以将每个require(x)
更改为Q.fcall(require,x)
并直接使用Q.all
,但是这两者都很慢(尽pipeQ仍然很慢),并且比直接promisifying模块更容易出错。 最好提供可能的最低级别的API。
诺言不是厄运的callback金字塔的银弹。 我曾经看过代码,即使承诺它看起来像厄运的金字塔。
你可以通过做这样的事情来摆脱金字塔,并保持callback风格:
// var app; // ...etc var paths = ['a','b','c','d']; setupNext(); function setupNext() { var p = paths.pop(); // or shift var next = paths.length > 0 ? setupNext : startApp require(p)(app, next); } function startApp() {}
- 为什么Mocha的`before()`函数传递是否带参数?
- 使用javascript从string(URL)中删除子string(URL)
- 如何使用正则expression式匹配高价值的Unicode字符?
- 为什么在使用MongoDB的$ push将新对象添加到数组时,为什么添加了ObjectID的_id?
- 为什么来自multer的req.file总是显示为undefined?
- Socket.IO:XHR轮询延迟断开连接
- / node_modules / jpegtran-bin / vendor / jpegtran:语法错误:“(”文件中意外
- Node.js – 安装后无法使用jQuery
- 在效率和优雅方面,添加和删除事件侦听器还是使用全局/高级variables来控制发射器事件逻辑更好?