使用异步函数从Node.js模块返回值

wor*_*art 5 javascript asynchronous node.js

我为我的Node.js项目编写了一个模块,它处理一些数据并且应该返回结果,如下所示:

var result = require('analyze').analyzeIt(data);
Run Code Online (Sandbox Code Playgroud)

问题在于analyze.js取决于异步功能.基本上它看起来像这样:

var analyzeIt = function(data) {
    someEvent.once('fired', function() {
        // lots of code ...
    });
    return result;
};
exports.analyzeIt = analyzeIt;
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用,因为result返回时仍然是空的.但是我该怎么解决呢?

T.J*_*der 8

你可以用它在API中解决它的方式来解决它:使用回调,它可能是一个简单的回调,一个事件回调或一个与某种类型的promise库相关的回调.前两个更像Node,承诺的东西非常好吃.

这是简单的回调方式:

var analyzeIt = function(data, callback) {
    someEvent.once('fired', function() {
        // lots of code ...

        // Done, send result (or of course send an error instead)
        callback(null, result); // By Node API convention (I believe),
                                // the first arg is an error if any,
                                // the second data if no error
    });
};
exports.analyzeIt = analyzeIt;
Run Code Online (Sandbox Code Playgroud)

用法:

require('analyze').analyzeIt(data, function(err, result) {
    // ...use err and/or result here
});
Run Code Online (Sandbox Code Playgroud)

但正如基里尔指出的那样,你可能想要analyzeIt返回一个EventEmitter然后发出一个data事件(或任何你喜欢的事件,真的),或者error出错:

var analyzeIt = function(data) {
    var emitter = new EventEmitter();

    // I assume something asynchronous happens here, so
    someEvent.once('fired', function() {
        // lots of code ...

        // Emit the data event (or error, of course)
        emitter.emit('data', result);
    });

    return emitter;
};
Run Code Online (Sandbox Code Playgroud)

用法:

require('analyze').analyzeIt(data)
    .on('error', function(err) {
        // ...use err here...
    })
    .on('data', function(result) {
        // ...use result here...
    });
Run Code Online (Sandbox Code Playgroud)

或者,再一次,某种承诺库.