Javascript 使方法同步执行

Javascript 使方法同步执行,javascript,asynchronous,callback,typescript,Javascript,Asynchronous,Callback,Typescript,您好,我不熟悉JavaScript/TypeScript,正在寻找通用解决方案,以表明ajax回调已经完成,以便可以执行依赖于回调结果的其他代码 例如,class Fee Calculator,它被实例化为服务类型,调用方法calculate Fee以显示服务的费用供客户同意 class FeeCalculator { private cost: number = 0; private serviceType: number = 0; private jsonAjax:

您好,我不熟悉JavaScript/TypeScript,正在寻找通用解决方案,以表明
ajax回调
已经完成,以便可以执行依赖于回调结果的其他代码

例如,class Fee Calculator,它被实例化为服务类型,调用方法calculate Fee以显示服务的费用供客户同意

class FeeCalculator {

    private cost: number = 0;
    private serviceType: number = 0;
    private jsonAjax: JsonAjax = null; 

    constructor(serviceType: number) {
        this.serviceType = serviceType;
        this.jsonAjax = new JsonAjax("/tmaMaster/JSONServlet");
    }

    public calculateFee(): void {

        // First, get the cost of the service from DB 
        this.cost = this.getServiceCost();  

        // calculate the fee and display it
        // Now, this code would still be executed even if the callback
        // didn't complete and therefore this.cost = 0, 
        // fee will be calculated wrongly
        var fee: number = this.calculateTheFee(cost); 
        alert(fee);
    }

    getServiceCost = () => {
        // IntegerWrapper is not relevant to this problem - just a primitive wrapper
        var cost: IntegerWrapper = new IntegerWrapper();
        this.execute("getServiceCost", this.serviceType, cost, this.setServiceCost);
    }

    // This is the callback 
    setServiceCost = (cost: IntegerWrapper) => {
        this.cost = IntegerWrapper.primitiveValue;
    } 

    private getFeeForTheCost(cost: number): number {
        return cost / 4;     
    }

    execute(command: string, requestDto: any, responseDto: any, callback: (responseDto: any) => void) {
        var commandObject: JsonCommand = new JsonCommand(command, requestDto);
        this.jsonAjax.call(commandObject, responseDto, callback);
    }
}
还将包括JsonAjax类:

import JsonExternalizable = require("./JsonExternalizable");

class JsonAjax {

    private READY_STATUS_CODE = 4;
    private url: string;

    constructor(url: string) {
        this.url = url;
    }

    private isCompleted(request: XMLHttpRequest) {
        return request.readyState === this.READY_STATUS_CODE;
    }

    call(requestDto: any, responseDto: any, callback: (responseDto: JsonExternalizable) => any) {


        // Create a request
        var request = new XMLHttpRequest();
        // Attach an event listener
        request.onreadystatechange = () => {
            var completed = this.isCompleted(request);
            if (completed && callback != null) {
                /*
                 * N.B. PLease note that readFromJsonString returns void, therefore below line must be called sperately from line below.
                 */
                responseDto.readFromJsonString(request.responseText);
                callback(responseDto);
            }
        };
        // Specify the HTTP verb and URL
        request.open('POST', this.url, true);
        // Send the request
        request.send(JSON.stringify(requestDto));

    }
    toString() {
        return "JsonAjax";
    }
}

export = JsonAjax;
问题是如何确保在
getServiceCost
完成后严格调用
calculateTheFee
,换句话说,使函数同步执行

我知道的方法:

  • 执行回调中需要
    cost
    值的所有其他步骤 它本身不热衷于该解决方案(如果有更多的价值呢 需要从数据库中提取,并且所有这些都需要 (计算)该代码的可读性将降低

  • 使用timeout(不够通用,因为我们不知道我们查询的内容有多大以及需要“睡眠”多长时间)


  • 另外,最好不要使用额外的库和插件(公司要求)

    您可以使用Observable:听起来是个好主意。问题是,这些本质上是异步操作;试图强迫它们同步会使你的应用程序看起来更慢。谢谢。同意,但同时有些位必须是同步的,否则应用程序根本无法工作。正如@MikeMcCaughan所提到的,承诺才是正确的选择。看看这段视频,它是关于离子的,但是概念解释得很好