diff --git a/src/lifecycle/index.ts b/src/lifecycle/index.ts index e86680d..c83f216 100644 --- a/src/lifecycle/index.ts +++ b/src/lifecycle/index.ts @@ -68,6 +68,8 @@ export class LifecycleManager { if (!Array.isArray(fnList)) { return; } + // lifecycle hook should only trigger one time + this.hookFnMap.delete(hookName); for (const hookFn of fnList) { await hookFn({ app: this.app, diff --git a/test/lifecycle.test.ts b/test/lifecycle.test.ts index dd64932..735df6f 100644 --- a/test/lifecycle.test.ts +++ b/test/lifecycle.test.ts @@ -50,4 +50,42 @@ describe('test/lifecycle.test.ts', () => { 'app_beforeClose', ]); }); + + it('should not trigger lifecyle multi times', async () => { + const appWithLifeCyclePath = path.resolve(__dirname, './fixtures/app_with_lifecycle'); + const app = await createApp(appWithLifeCyclePath); + const lifecycleList = app.container.get(LifecycleList).lifecycleList; + await Promise.all([ + app.run(), + app.run(), + app.run(), + ]); + + await Promise.all([ + app.close(), + app.close(), + app.close(), + ]); + + assert.deepStrictEqual(lifecycleList, [ + 'pluginA_configWillLoad', + 'pluginB_configWillLoad', + 'app_configWillLoad', + 'pluginA_configDidLoad', + 'pluginB_configDidLoad', + 'app_configDidLoad', + 'pluginA_didLoad', + 'pluginB_didLoad', + 'app_didLoad', + 'pluginA_willReady', + 'pluginB_willReady', + 'app_willReady', + 'pluginA_didReady', + 'pluginB_didReady', + 'app_didReady', + 'pluginA_beforeClose', + 'pluginB_beforeClose', + 'app_beforeClose', + ]); + }); });