Running an async function before express.js start

柔情痞子 提交于 2019-12-21 16:56:06

问题


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


回答1:


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;
});



回答2:


Take a look at the async package. For your needs you should go with the waterfall control flow provided by the async package. You cann 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.



来源:https://stackoverflow.com/questions/41364072/running-an-async-function-before-express-js-start

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!