最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Importingexporting only after certain promises have resolved - Stack Overflow

programmeradmin1浏览0评论

Let's say I have a file containing certain promises, that when executed in order, prepares an input file 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";

Let's say I have a file containing certain promises, that when executed in order, prepares an input file 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";

If I run node prepareInput.js, the line step1().then(step2).then(step3) gets executed and creates the file.

How can I alter this so that when other files attempt to retrieve fileName from this module, step1().then(step2).then(step3); is run and pleted before fileName is exposed? Something along the line of:

// 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 beginner here; apologize beforehand if my approach makes pletely no sense... :)

Share Improve this question edited Jul 11, 2016 at 17:20 Dave Newton 160k27 gold badges260 silver badges307 bronze badges asked Jul 11, 2016 at 15:00 PupperPupper 2,3553 gold badges22 silver badges29 bronze badges 4
  • 2 Why not require('./prepareInput').fileName.then(function(inputFileName) {...})? – Yury Tarabanko Commented Jul 11, 2016 at 15:08
  • 1 I mean once your code was "infected" with async effect you can't get rid of it everything that uses the code bees async. – Yury Tarabanko Commented Jul 11, 2016 at 15:10
  • What is first()..? – Redu Commented Jul 11, 2016 at 15:14
  • @redu: Sorry that meant to say "step1". Yury: trying your suggestion... – Pupper Commented Jul 11, 2016 at 15:17
Add a ment  | 

1 Answer 1

Reset to default 9

You can't directly export the results of something retrieved asynchronously because export is synchronous, so it happens before any async results have been retrieved. The usual solution here is to export a method that returns a promise. The caller can then call that method and use that promise to get the desired async result.

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

The caller then does this:

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

One thing to keep is mind is that if any operation in a sequence of things is asynchronous, then the whole operation bees asynchronous and no caller can then fetch the result synchronously. Some people refer to asynchronous as "contagious" in this way. So, if any part of your operation is asynchronous, then you must create an asynchronous interface for the eventual result.


You can also cache the promise so it is only ever run once per app:

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

The caller then does this:

require('yourmodule').then(function(filename) {
    // use filename here
});
发布评论

评论列表(0)

  1. 暂无评论