【问题标题】:Importing / exporting only after certain promises have resolved仅在某些承诺解决后导入/导出
【发布时间】:2016-11-13 14:12:21
【问题描述】:

假设我有一个包含某些承诺的文件,当按顺序执行时,准备一个输入文件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";

如果我运行node prepareInput.jsstep1().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);
              

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

【问题讨论】:

  • 为什么不require('./prepareInput').fileName.then(function(inputFileName) {...})
  • 我的意思是一旦你的代码被异步效果“感染”了,你就无法摆脱它,所有使用代码的东西都会变成异步的。
  • 什么是first()..?
  • @redu:对不起,意思是说“step1”。 Yury:试试你的建议……

标签: javascript node.js promise


【解决方案1】:

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

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

然后调用者这样做:

require('yourmodule')().then(function(filename) {
    // use filename here
});

要记住的一点是,如果一系列事物中的任何操作是异步的,那么整个操作将变为异步,并且调用者无法同步获取结果。有些人以这种方式将异步称为“传染性”。因此,如果您的操作的任何部分是异步的,那么您必须为最终结果创建一个异步接口。


您还可以缓存承诺,以便每个应用只运行一次:

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

然后调用者这样做:

require('yourmodule').then(function(filename) {
    // use filename here
});

【讨论】:

  • 不幸的是,我的案例属于“如果一系列事物中的任何操作是异步的”。我将不得不研究异步接口或改变我的方法。不过,谢谢你的详细解释!
猜你喜欢
  • 2020-09-27
  • 1970-01-01
  • 2014-08-07
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2015-06-24
相关资源
最近更新 更多