问题
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