如何在 bluebird 承诺中修改 express.res,并在另一个承诺中使用 res?
How can you modify express.res within bluebird promises, and use res within another promise?
我可能想多了,但请耐心等待...如果我有以下代码
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
会怎样?我是否需要每次 return res
并将 someJson 存储在 res 中?而且,如果我必须使用 next() 会怎样?如何确保 res
在我的承诺链末尾被修改?我不能在 finally()
中做到这一点,我是否必须在我最后的承诺中做到这一点?
如果您真的希望能够从您的函数中改变 res
,您必须传递它。我认为传递它的 easiest/cleanest 方法是像这样使用 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
。您可以将所有功能移动到一个或多个服务,并让控制器根据服务 return 确定 res
需要发生什么。希望这会导致 maintainable/testable 代码。
更新 非常简单的服务示例
// 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 文件。无论您导出什么,都将是您的 "public" 方法。
// 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
});
}
我可能想多了,但请耐心等待...如果我有以下代码
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
会怎样?我是否需要每次 return res
并将 someJson 存储在 res 中?而且,如果我必须使用 next() 会怎样?如何确保 res
在我的承诺链末尾被修改?我不能在 finally()
中做到这一点,我是否必须在我最后的承诺中做到这一点?
如果您真的希望能够从您的函数中改变 res
,您必须传递它。我认为传递它的 easiest/cleanest 方法是像这样使用 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
。您可以将所有功能移动到一个或多个服务,并让控制器根据服务 return 确定 res
需要发生什么。希望这会导致 maintainable/testable 代码。
更新 非常简单的服务示例
// 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 文件。无论您导出什么,都将是您的 "public" 方法。
// 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
});
}