使方法同步执行

时间:2016-04-15 13:05:57

标签: javascript asynchronous callback typescript

美好的一天,我是JavaScript / TypeScript的新手,并寻找通用的解决方案来表明ajax callback已经完成,以便其他依赖回调结果的代码可以执行。

例如,课程费用计算器,它通过服务类型实例化,并且调用方法计算费用以显示服务费用以供客户同意。

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;

问题是如何确保在calculateTheFee之后严格调用getServiceCost,换句话说,make函数是否同步执行?

我知道的方式:

  1. 执行回调中需要cost值的所有其他步骤 本身。不热衷于那个解决方案(如果有更多的价值观会怎样 需要从数据库中提取所需的所有内容 计算)该代码的可读性将降低。

  2. 使用超时(不够通用,因为我们不知道我们查询的内容有多大以及需要多长时间"睡眠")

  3. P.S。最好不使用额外的库和插件(公司要求)

0 个答案:

没有答案