executor: move "booted" and cb() to the next tick

Fix executor to always emit the "booted" event and call the callback
in the next tick of the event loop, regardless of whether there are any
async boot scripts.

Before this change, adding a listener for "booted" event was cumbersome:

    boot(app);
    if (app.booting)
      app.on('booted', handler);
    else
      handler();

With the fix in place, one can simply write the following:

    boot(app);
    app.on('booted', handler);
This commit is contained in:
Miroslav Bajtoš 2016-02-22 11:01:06 +01:00
parent e9afcaac70
commit b0e5a0bc63
2 changed files with 10 additions and 5 deletions

View File

@ -43,7 +43,12 @@ module.exports = function execute(app, instructions, callback) {
function(done) {
enableAnonymousSwagger(app, instructions);
done();
}], function(err) {
},
// Ensure both the "booted" event and the callback are always called
// in the next tick of the even loop.
// See http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
process.nextTick,
], function(err) {
app.booting = false;
if (err) return callback(err);

View File

@ -66,15 +66,15 @@ describe('executor', function() {
});
});
it('should emit the `booted` event', function(done) {
it('should emit the `booted` event in the next tick', function(done) {
boot.execute(app, dummyInstructions, function(err) {
expect(err).to.be.undefined();
});
app.on('booted', function() {
// This test fails with a timeout when the `booted` event has not been
// emitted correctly
done();
});
boot.execute(app, dummyInstructions, function(err) {
expect(err).to.be.undefined();
});
});
it('should work when called synchronously', function() {