Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing / exporting only after certain promises have resolved

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 completed 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 completely no sense... :)

like image 485
Pupper Avatar asked Jul 11 '16 15:07

Pupper


People also ask

What happens when a Promise is resolved?

A Promise that is resolved with the given value, or the promise passed as value, if the value was a promise object. It may be either fulfilled or rejected — for example, resolving a rejected promise will still result in a rejected promise.

Can a Promise be resolved more than once?

No. It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.

Does Promise all resolve promises in order?

Here, Promise. all() method is the order of the maintained promises. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.

Does import return a Promise?

Dynamic import of modulesIt returns a promise and starts an asynchronous task to load the module. If the module was loaded successfully, then the promise resolves to the module content, otherwise, the promise rejects.


1 Answers

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 becomes 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
});
like image 92
jfriend00 Avatar answered Oct 20 '22 00:10

jfriend00