我试图绕着Promises(一个共同的主题,我知道)。我有基本的想法,但我没有实施它们。
我试图构建一个对象,它根据目录的内容公开一组函数。我使用蓝鸟来宣传fs图书馆。然后读入目录的文件,构建对象,并返回结果。
var Promise = require('bluebird'),
fs = Promise.promisifyAll(require('fs'));
var services = {};
return fs.readdirAsync('./path/to/file/')
.each(function (filename) {
//trim off the file extension and assign the export function
services[filename.replace(/\.[^/.]+$/, "")] = function(request) {
request.esbOperation = filename;
otherFunctionCall(request);
}
})
.then(function() {
return {services: services};
})
.catch(function(err){
console.log(err);
});
我尝试了各种各样的东西,但返回的对象通常看起来像这样:
Promise {
_bitField: 167772160,
_fulfillmentHandler0: undefined,
_rejectionHandler0:
{ services:
{ function1: [Function],
function2: [Function],
function3: [Function],
},
_promise0: undefined,
_receiver0: undefined }
如何在履行处理程序中获得结果? 如何让它返回已解析的对象而不是Promise对象(我已尝试在各个地方解决/拒绝,但我做错了)?
答案 0 :(得分:0)
您无法返回已解析的对象。这就是重点。您的功能已经返回很久就可以获得您获得的数据。
所以你的两个主要选择是:
接受你有一个返回一个promise的函数(这不是坏事!)。想要获得分辨率值的消费者可以在其上调用.then()
。
让你的函数进行回调并在你的函数中承诺调用它。这种方式首先违背了使用promises的目的,但会使你的函数签名更像“节点”:
function myFunction(callback) {
var Promise = require('bluebird'),
fs = Promise.promisifyAll(require('fs'));
var services = {};
fs.readdirAsync('./path/to/file/')
.each(function (filename) {
//trim off the file extension and assign the export function
services[filename.replace(/\.[^/.]+$/, "")] = function(request) {
request.esbOperation = filename;
otherFunctionCall(request);
}
})
.then(function() {
callback(null, {services: services});
}, function(err){
callback(err);
});
}
正如Bergi所指出的那样,既然你正在使用Bluebird,那么仍然可以达到相同目的的#2选项的改进是使用.asCallback
而不是.then
。
这里需要注意的一些事项:
then()
来获取管道中的{services: services}
对象,以便将其传递给回调return
语句。这是因为.asCallback()
返回一个promise,它允许你的函数的调用者选择是否要使用返回的promise 或使用回调。function myFunction(callback) {
var Promise = require('bluebird'),
fs = Promise.promisifyAll(require('fs'));
var services = {};
return fs.readdirAsync('./path/to/file/')
.each(function (filename) {
//trim off the file extension and assign the export function
services[filename.replace(/\.[^/.]+$/, "")] = function(request) {
request.esbOperation = filename;
otherFunctionCall(request);
}
return {services: services};
})
.then(function() { return {services: services} })
.asCallback(callback);
}