admin管理员组

文章数量:1200973

I want to run an async operation (for example, wait for a URL call to complete) before I start my app. I don't know how to do that (since it's an upper-level application - no async/await here).

www.js:

var app = require('./app');
var http = require('http');
const port = '3000';
app.set('port', port);
var server = http.createServer(app);
server.listen(port);

app.js:

var express = require('express');
var app = express();
var Promise = require('bluebird');

# HERE IS WHERE I WANT TO "AWAIT" AN ASYNCHRONOUS CALL. 
# I KNOW I CAN'T USE AWAIT BECAUSE I'M NOT WITHIN 
# AN "ASYNC" ANNOTATED FUNCTION. EXAMPLE:
const data = await Promise.promisify(fs.readFile('DATA'));

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
module.exports = app;

I thought about wrapping all of app.js with a Promise.promisify() so I can use async await withing it. But I'm not sure how that would be handled in www.js, since it is not invoked, as in app() but passed on to http.createServer

I want to run an async operation (for example, wait for a URL call to complete) before I start my app. I don't know how to do that (since it's an upper-level application - no async/await here).

www.js:

var app = require('./app');
var http = require('http');
const port = '3000';
app.set('port', port);
var server = http.createServer(app);
server.listen(port);

app.js:

var express = require('express');
var app = express();
var Promise = require('bluebird');

# HERE IS WHERE I WANT TO "AWAIT" AN ASYNCHRONOUS CALL. 
# I KNOW I CAN'T USE AWAIT BECAUSE I'M NOT WITHIN 
# AN "ASYNC" ANNOTATED FUNCTION. EXAMPLE:
const data = await Promise.promisify(fs.readFile('DATA'));

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
module.exports = app;

I thought about wrapping all of app.js with a Promise.promisify() so I can use async await withing it. But I'm not sure how that would be handled in www.js, since it is not invoked, as in app() but passed on to http.createServer

Share Improve this question edited Dec 29, 2016 at 15:32 eran asked Dec 28, 2016 at 14:29 eraneran 15.1k37 gold badges104 silver badges148 bronze badges 3
  • Have you looked up tutorials on promises? Here's a good start: github.com/kriskowal/q – Dave Swersky Commented Dec 28, 2016 at 14:32
  • What asynchronous call? Also, app.js doesn't show any exports, and yet you're using it as though it had. – T.J. Crowder Commented Dec 28, 2016 at 14:35
  • @T.J.Crowder you are right. My bad. Edited to add export and illustrate reading a file (I know there's a sync version. Let's assume there isn't or I'm using some other Promised call) – eran Commented Dec 29, 2016 at 15:33
Add a comment  | 

2 Answers 2

Reset to default 18

From what you've said, app.js is presumably exporting something (perhaps app?) but that something isn't ready to be used until an asynchronous call (which I don't think you've shown) is complete.

Assuming that's all true, then what app.js exports needs to provide a way for the things using it to wait until it's ready. One way to do that is to use a promise.

Assuming what you're waiting for isn't promise-ified, then:

app.js:

var express = require('express');
var app = express();
exports.appPromise = new Promise(function(resolve, reject) {
    startTheAsyncOperation(function(err, result) {
        if (err) {
            reject(err);
            return;
        }
        app.set('views', path.join(__dirname, 'views'));
        app.set('view engine', 'jade');
        app.use(express.static(path.join(__dirname, 'public')));
        app.use('/', routes);
        resolve(app);
    });
});

then in www.js:

var appPromise = require('./app').appPromise;
var http = require('http');
const port = '3000';
appPromise.then(function(app) {
    app.set('port', port);
    var server = http.createServer(app);
    server.listen(port);
});

Of course, if the async thing you're waiting for provides a promise to you, you don't need new Promise in app.js; instead:

var express = require('express');
var app = express();
exports.appPromise = startTheAsyncOperation().then(function() {
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');
    app.use(express.static(path.join(__dirname, 'public')));
    app.use('/', routes);
    return app;
});

Take a look at the async package. For your needs, you should go with the waterfall control flow provided by the async package. You can have a look as it is very well documented.

You can wrap your code with the waterfall function and this part of your code will be running synchronously.

Edit: Updated Link, but the accepted answer has a better approach imho.

本文标签: javascriptRunning an async function before expressjs startStack Overflow