我可能会过度思考这个,但请耐心等待......如果我有以下代码
app.get('/api/endpoint', function(req, res, next) {
new Promise(function() {
// doing something that takes lots of code
return someJson
})
.then(function(someJson) {
// analyze someJson with lots of code
})
.then(function() {
// do more
})
// chain a bunch more promises here
.then(function() {
res.status(200).send(message)
})
.catch(function(err) {
// error handling
})
.finally(function() {
// clean up
})
})
如果承诺链变得很长,导航端点可能会很痛苦。因此,我希望承诺的每一步都是它自己的功能(以简化上述代码)。所以我可以重写前2个承诺:
function findSomeJson() {
return new Promise(function() {
// doing something that takes lots of code
return someJson
})
}
function analyzeSomeJson(someJson) {
return new Promise(function(someJson) {
// analyze someJson with lots of code
})
}
现在,这些函数中的每一个都可以在原始示例中使用,如下所示:
findSomeJson()
.then(function(someJson) {
return analyzeSomeJson(someJson)
})
// etc...
但是,如果我需要在这些承诺中调整res
,会发生什么?我是否每次都需要返回res
并在res中存储someJson?而且,如果我必须使用next()会发生什么?如何确保在我的保证链末尾修改res
?我不能在finally()
中这样做,我是否必须在最后的承诺中这样做?
答案 0 :(得分:1)
如果你真的希望能够在你的功能中改变res
,你必须传递它。我认为传递它的最简单/最简洁的方法是使用bind,如下所示:
findSomeJson()
.then(analyzeSomeJson.bind(this, res))
.then(doMore.bind(this, res))
.then(andEvenMore.bind(this, res))...
然后analyzeSomeJson
定义如下所示:
// .bind makes it so that res is the first argument when it is called
function analyzeSomeJson(res, someJson) {
return new Promise(function(someJson) {
// analyze someJson with lots of code
})
}
但我可能会尽量避免绕过res
,以便只有您的控制器必须知道req
和res
。您可以将所有功能移动到一个或多个服务,并让控制器根据服务返回的内容确定res
需要执行的操作。希望这将导致可维护/可测试的代码。
更新非常简单的服务示例
// endpoint.js
var jsonService = require('./jsonService.js');
app.get('/api/endpoint', function(req, res, next) {
jsonService.getJson()
// chain a bunch more promises here
.then(function(json) {
if(json === null) {
return res.status(404).send('Not Found');
}
res.status(200).send(json);
})
.catch(function(err) {
// error handling
});
});
有许多方法可以实现您的服务,但实际上它只是您需要的“controller”或endpoint.js中的另一个.js文件。无论你出口什么,都将是你的“公共”方法。
// jsonService.js
// "public" methods
var service = {
getJson: function() {
return findSomeJson().then(analyzeSomeJson);
}
};
module.exports = service;
// "private" methods
function findSomeJson() {
return new Promise(function() {
// doing something that takes lots of code
return someJson
});
}
function analyzeSomeJson(someJson) {
return new Promise(function(someJson) {
// analyze someJson with lots of code
});
}