From 901b6944c34f6e73453be384ed656e5141636a98 Mon Sep 17 00:00:00 2001 From: killagu Date: Tue, 26 Jun 2018 11:55:50 +0800 Subject: [PATCH 1/2] feat: impl willReady Refs: https://github.com/eggjs/egg/issues/2520 --- appveyor.yml | 2 +- lib/ready.js | 17 +++++++++++++++-- test/ready.test.js | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2efd0fa..807ad4f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,6 @@ install: test_script: - node --version - npm --version - - npm run ci + - npm run test build: off diff --git a/lib/ready.js b/lib/ready.js index e85dfbe..43d104e 100644 --- a/lib/ready.js +++ b/lib/ready.js @@ -5,6 +5,8 @@ const once = require('once'); const ready = require('get-ready'); const uuid = require('uuid'); const debug = require('debug')('ready-callback'); +const WILL_READY_CALLBACKS = Symbol('willReadyCallbacks'); +const TRIGGER_WILL_READY = Symbol('triggerWillReady'); const defaults = { timeout: 10000, @@ -29,12 +31,13 @@ class Ready extends EventEmitter { this.opt = opt || {}; this.isError = false; this.cache = new Map(); + this[WILL_READY_CALLBACKS] = []; setImmediate(() => { // fire callback directly when no registered ready callback if (this.cache.size === 0) { debug('Fire callback directly'); - this.ready(true); + this[TRIGGER_WILL_READY](); } }); } @@ -52,6 +55,7 @@ class Ready extends EventEmitter { // delegate API to object obj.ready = this.ready.bind(this); obj.readyCallback = this.readyCallback.bind(this); + obj.willReady = this.willReady.bind(this); // only ready once with error this.once('error', err => obj.ready(err)); @@ -121,11 +125,20 @@ class Ready extends EventEmitter { if (this.cache.size === 0) { debug('[%s] Fire callback async', id); - this.ready(true); + this[TRIGGER_WILL_READY](); } return this; } + willReady(fn) { + this[WILL_READY_CALLBACKS].push(fn); + } + + [TRIGGER_WILL_READY]() { + return Promise.all(this[WILL_READY_CALLBACKS].map(fn => fn())) + .then(() => this.ready(true)) + .catch(e => this.ready(e)); + } } // Use ready-callback with options diff --git a/test/ready.test.js b/test/ready.test.js index 5ebea0a..06ee042 100644 --- a/test/ready.test.js +++ b/test/ready.test.js @@ -462,4 +462,19 @@ describe('Ready', function() { assert(ready.obj === obj1); assert(ready.obj !== obj2); }); + + describe('willReady', function() { + it('should fire willRead callbacks before ready', function() { + const obj = new EventEmitter(); + const ready = new Ready(); + ready.mixin(obj); + const endA = obj.readyCallback('a'); + const spyWillReady = spy(); + obj.willReady(spyWillReady); + setTimeout(endA, 1); + setTimeout(function() { + assert.strictEqual(spyWillReady.callCount, 1); + }, 10); + }); + }); }); From a8d1288a17636d4ee20378bfa3c77fd707d8dfa1 Mon Sep 17 00:00:00 2001 From: killagu Date: Tue, 26 Jun 2018 12:21:20 +0800 Subject: [PATCH 2/2] support node v4 --- .travis.yml | 3 ++- appveyor.yml | 3 ++- lib/ready.js | 9 ++++++++- package.json | 4 ++-- test/ready.test.js | 25 ++++++++++++++++++++++++- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ec1467..9edb713 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ language: node_js node_js: - '4' - '6' - - '7' + - '8' + - '10' install: - npm i npminstall && npminstall script: diff --git a/appveyor.yml b/appveyor.yml index 807ad4f..d3108c3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,8 @@ environment: matrix: - nodejs_version: '4' - nodejs_version: '6' - - nodejs_version: '7' + - nodejs_version: '8' + - nodejs_version: '10' install: - ps: Install-Product node $env:nodejs_version diff --git a/lib/ready.js b/lib/ready.js index 43d104e..f2b4487 100644 --- a/lib/ready.js +++ b/lib/ready.js @@ -135,7 +135,14 @@ class Ready extends EventEmitter { } [TRIGGER_WILL_READY]() { - return Promise.all(this[WILL_READY_CALLBACKS].map(fn => fn())) + return Promise.all(this[WILL_READY_CALLBACKS] + .map(fn => { + try { + return fn(); + } catch (e) { + return Promise.reject(e); + } + })) .then(() => this.ready(true)) .catch(e => this.ready(e)); } diff --git a/package.json b/package.json index 0a827fe..ca9d01d 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "devDependencies": { "autod": "^2.7.1", - "egg-bin": "^2.0.2", + "egg-bin": "^1.0.0", "egg-ci": "^1.1.0", "eslint": "^3.15.0", "eslint-config-egg": "^3.2.0", @@ -45,6 +45,6 @@ "node": ">=4.0.0" }, "ci": { - "version": "4, 6, 7" + "version": "4, 6, 8, 10" } } diff --git a/test/ready.test.js b/test/ready.test.js index 06ee042..4e755f8 100644 --- a/test/ready.test.js +++ b/test/ready.test.js @@ -464,7 +464,7 @@ describe('Ready', function() { }); describe('willReady', function() { - it('should fire willRead callbacks before ready', function() { + it('should fire willRead callbacks before ready', function(done) { const obj = new EventEmitter(); const ready = new Ready(); ready.mixin(obj); @@ -474,7 +474,30 @@ describe('Ready', function() { setTimeout(endA, 1); setTimeout(function() { assert.strictEqual(spyWillReady.callCount, 1); + done(); }, 10); }); + + describe('willReady failed', function() { + it('should ready error', function(done) { + const obj = new EventEmitter(); + const ready = new Ready(); + ready.mixin(obj); + const endA = obj.readyCallback('a'); + const willReadyThrows = function() { + throw new Error('mock error'); + }; + obj.willReady(willReadyThrows); + let err; + obj.ready(function(e) { + err = e; + }); + setTimeout(endA, 1); + setTimeout(function() { + assert.strictEqual(err && err.message, 'mock error'); + done(); + }, 10); + }); + }); }); });