0

我正在尝试在我用来将数据拉入我的反应应用程序的 javascript 帮助程序类中按环境设置 API 端点。它看起来像这样:

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。

4

1 回答 1

2

构造函数异步设置这些道具。等到fetch("/environment") resolve 然后 call很好helper.fetchData(),但如果你在实例化后过早调用它,那么它会失败。

您需要一些机制来确保 helper 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;
    }
}
于 2020-11-13T00:49:52.227 回答