From e6e5f23cf8481db31b94c18244f404dd3374ad90 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Mon, 2 Mar 2020 00:39:15 +0200 Subject: [PATCH] fix API calls when Backend isn't ready yet --- ext/bg/js/backend.js | 5 +++++ ext/mixed/js/api.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 07dca370..e849bc69 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -48,6 +48,7 @@ class Backend { this.messageToken = yomichan.generateId(16); this._messageHandlers = new Map([ + ['isBackendReady', this._onApiIsBackendReady.bind(this)], ['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)], ['optionsGet', this._onApiOptionsGet.bind(this)], ['optionsGetFull', this._onApiOptionsGetFull.bind(this)], @@ -267,6 +268,10 @@ class Backend { // Message handlers + async _onApiIsBackendReady() { + return true; + } + async _onApiOptionsSchemaGet() { return this.getOptionsSchema(); } diff --git a/ext/mixed/js/api.js b/ext/mixed/js/api.js index 26f4389d..fa61a1e2 100644 --- a/ext/mixed/js/api.js +++ b/ext/mixed/js/api.js @@ -122,6 +122,30 @@ function apiGetDefaultAnkiFieldTemplates() { } function _apiInvoke(action, params={}) { + if (!_isBackendReady) { + if (_isBackendReadyPromise === null) { + _isBackendReadyPromise = new Promise((resolve) => (_isBackendReadyResolve = resolve)); + const checkBackendReady = async () => { + try { + if (await _apiInvokeRaw('isBackendReady')) { + _isBackendReady = true; + _isBackendReadyResolve(); + } + } catch (e) { + // NOP + } + setTimeout(checkBackendReady, 100); // poll Backend until it responds + }; + checkBackendReady(); + } + return _isBackendReadyPromise.then( + () => _apiInvokeRaw(action, params) + ); + } + return _apiInvokeRaw(action, params); +} + +function _apiInvokeRaw(action, params={}) { const data = {action, params}; return new Promise((resolve, reject) => { try { @@ -148,3 +172,7 @@ function _apiInvoke(action, params={}) { function _apiCheckLastError() { // NOP } + +let _isBackendReady = false; +let _isBackendReadyResolve = null; +let _isBackendReadyPromise = null;