根据promise调用的结果构建一个对象

时间:2017-01-25 21:17:26

标签: node.js promise

我试图绕着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对象(我已尝试在各个地方解决/拒绝,但我做错了)?

1 个答案:

答案 0 :(得分:0)

您无法返回已解析的对象。这就是重点。您的功能已经返回很久就可以获得您获得的数据。

所以你的两个主要选择是:

  1. 接受你有一个返回一个promise的函数(这不是坏事!)。想要获得分辨率值的消费者可以在其上调用.then()

  2. 让你的函数进行回调并在你的函数中承诺调用它。这种方式首先违背了使用promises的目的,但会使你的函数签名更像“节点”:

  3. 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}对象,以便将其传递给回调
    • 在函数的第6行有一个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);
    }