#javascript #class-constructors
#javascript #конструкторы классов
Вопрос:
Я пытаюсь установить конечные точки API по среде в вспомогательном классе javascript, который я использую для извлечения данных в мое приложение react. Это выглядит так:
import axios from 'axios';
class QueryHelper {
endpoints;
SupportEndpoint;
MemberEndpoint;
constructor() {
debugger
// get the endpoints set
fetch('/environment')
.then(response => response.json())
.then(data => this.endpoints = data) // set the endpoints var with the json payload with all the endpoint and env data
.then(() => {
this.SupportEndpoint = this.endpoints.supportBaseUrl;
this.MemberEndpoint = this.endpoints.memberBaseUrl;
});
}
async fetchData(resource) {
const resp = await axios.get(this.SupportEndpoint '/' resource);
return resp.data;
}
}
export default QueryHelper;
Он будет использоваться следующим образом:
let helper = new QueryHelper();
helper.fetchData('MemberProfile')
.then(response => response.json())
.then(//do some other stuff);
Когда я нажимаю точку останова, я могу пройти через конструктор, и различные конечные точки, похоже, устанавливаются так, как ожидалось. Но когда fetchData
вызывается метод SupportEndpoint
(и любая другая конечная точка) undefined
, и вызов ajax завершается с ошибкой 404.
Комментарии:
1.
fetch
это асинхронная операция и возвращает обещание, поэтому вам нужно дождаться ее завершения. Не уверен, почему вы используете axios и fetch в своем коде.
Ответ №1:
Конструктор асинхронно устанавливает эти реквизиты. Можно подождать до fetch("/environment")
разрешения, а затем вызвать helper.fetchData()
, но если вы вызовете его слишком рано после создания экземпляра, то произойдет сбой.
Вам нужен какой-то механизм для обеспечения помощника isRready
.
function defer() {
let resolve, reject;
const promise = new Promise((r, j) => {
resolve = r;
reject = j;
});
return { resolve, reject, promise };
}
class QueryHelper {
endpoints;
SupportEndpoint;
MemberEndpoint;
_isReady;
_d;
get isReady() {
if (this._isReady) return Promise.resolve(true);
if (!this._d) {
this._d = defer();
}
return this._d.promise;
}
constructor() {
fetch('/environment')
.then(response => response.json())
.then(data => this.endpoints = data) // set the endpoints var with the json payload with all the endpoint and env data
.then(() => {
this.SupportEndpoint = this.endpoints.supportBaseUrl;
this.MemberEndpoint = this.endpoints.memberBaseUrl;
this._isReady = true;
if (this._d amp;amp; this._d.resolve) this._d.resolve(true);
});
}
async fetchData(resource) {
await this.isReady;
const resp = await axios.get(this.SupportEndpoint '/' resource);
return resp.data;
}
}