仅在某些承诺解决后才导入/导出

Pup*_*per 7 javascript node.js promise

假设我有一个包含某些promise的文件,当按顺序执行时,准备一个输入文件input.txt.

// prepareInput.js

var step1 = function() {
    var promise = new Promise(function(resolve, reject) {
        ...
    });
    return promise;
};
              
var step2 = function() {
    var promise = new Promise(function(resolve, reject) {
        ...
    });
    return promise;
};
              
var step3 = function() {
    var promise = new Promise(function(resolve, reject) {
        ...
    });
    return promise;
};

step1().then(step2).then(step3);

exports.fileName = "input.txt";
Run Code Online (Sandbox Code Playgroud)

如果我运行node prepareInput.js,则step1().then(step2).then(step3)执行该行并创建该文件.

如何更改此设置,以便在其他文件尝试fileName从此模块检索时,step1().then(step2).then(step3);在fileName公开之前运行并完成?沿线的东西:

// prepareInput.js
...

exports.fileName = 
    step1().then(step2).then(step3).then(function() {
        return "input.txt";
    });


// main.js
var prepareInput = require("./prepareInput");
var inputFileName = require(prepareInput.fileName);
              
Run Code Online (Sandbox Code Playgroud)

Node.js初学者在这里; 如果我的方法完全没有意义,请事先道歉...... :)

jfr*_*d00 7

您不能直接导出异步检索的结果,因为导出是同步的,所以它在检索到任何异步结果之前发生.这里通常的解决方案是导出一个返回promise的方法.然后调用者可以调用该方法并使用该promise来获得所需的异步结果.

module.exports = function() {
    return step1().then(step2).then(step3).then(function() {
        // based on results of above three operations, 
        // return the filename here
        return ...;
    });
}
Run Code Online (Sandbox Code Playgroud)

然后调用者执行此操作:

require('yourmodule')().then(function(filename) {
    // use filename here
});
Run Code Online (Sandbox Code Playgroud)

要记住的一件事是,如果一系列事物中的任何操作是异步的,那么整个操作就变为异步,然后调用者不能同步获取结果.有些人以这种方式将异步称为"传染性".因此,如果操作的任何部分是异步的,则必须为最终结果创建异步接口.


您还可以缓存承诺,因此每个应用程序只运行一次:

module.exports = step1().then(step2).then(step3).then(function() {
    // based on results of above three operations, 
    // return the filename here
    return ...;
});
Run Code Online (Sandbox Code Playgroud)

然后调用者执行此操作:

require('yourmodule').then(function(filename) {
    // use filename here
});
Run Code Online (Sandbox Code Playgroud)