Javascript class 构造函数未按预期设置 class 变量

Javascript class constructor not setting class variables as expected

我正在尝试在 javascript 助手中按环境设置 API 端点 class 我正在使用它来将数据拉入我的 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.

构造函数正在异步设置这些道具。等到 fetch("/environment") resolve 然后调用 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 && this._d.resolve) this._d.resolve(true);
            });
    }

    
    async fetchData(resource) {
        await this.isReady;
        const resp = await axios.get(this.SupportEndpoint + '/' + resource);
        return resp.data;
    }
}