Вызов асинхронной функции внутри машинного цикла for и тупика nhibernate - PullRequest
0 голосов
/ 02 сентября 2018

Я пишу http пост-вызов внутри цикла for с машинописью.

При отладке метода в бэкэнде я заметил, что он обрабатывает запросы одновременно.

Например, допустим, сервер должен запустить 2 метода M1(), а затем M2() на один запрос. Для теста с n = 2. Сервер выполняет M1() для запроса 1, M1() для запроса 2, затем M2() для запроса 2 и, наконец, M2() для запроса 2.

Затем после _session.commit() в методе intercept генерируется исключение. Описание исключения:

NHibernate.StaleObjectStateException: 'Строка была обновлена ​​или удалена другой транзакцией (или отображение несохраненного значения было неправильным): [Server.Model.Identity.ApplicationRole # 3]'

Код:

public calculate(index?: number): void {
    for (var i = 0; i < this.policy.coverages.length; i++) {
        this.callCalculate(i);
    }
}

public callCalculate(i: number): void {
    this.premiumCalculationParams = this.policy.createPremiumCalculationParams();

    if (!this.premiums) {
        this.premiums = new Array(this.policy.coverages.length);
    }

    this.offerService.calculatePremiums(this.policy, i).then((result: any) => {

        this.premiums[i] = new Array<Premium>();
        this.surpremiums = new Array<PremiumResult>();

        if (result.data && result.data.premiumTable && result.data.premiumTable.premiumPayment && result.data.premiumTable.premiumPayment.premiums && result.data.premiumTable.premiumPayment.premiums.length > 0) {
            _.each(result.data.premiumTable.premiumPayment.premiums, (premiumValue: any) => {
                let premium: Premium = new Premium();
                premium.setPremium(premiumValue);
                this.premiums[i].push(premium);
                this.policy.getCoverage(i).premiumPayment.premiums = angular.copy(this.premiums[i]);
            });

            if (result.data && result.data.results && result.data.results.length > 0) {
                _.each(result.data.results, (premiumValuel: any) => {
                    let sp = new PremiumResult();
                    sp.setPremiumResult(premiumValuel);
                    sp.premiums = new Array<Premium>();
                    _.each(premiumValuel.premiums, (premiumValue: any) => {
                        let premium: Premium = new Premium();
                        premium.setPremium(premiumValue);
                        sp.premiums.push(premium);
                    });
                    this.surpremiums.push(sp);
                });
            }

            console.log(this.surpremiums);
        }

        if (result.data && result.data.premiumTable && result.data.premiumTable.messageList && result.data.premiumTable.messageList.messages && result.data.premiumTable.messageList.messages.length > 0) {
            _.each(result.data.premiumTable.messageList.messages, (message: any) => {
                let messageType: any = MessageType[message.messageLevel.toString()];
                this.messages.push(new Message(messageType, "premiums", message.messageContent, this.premiums[i]));
            });

        }

    }, (err: any) => {
        this.premiums[i] = null;
        this.surpremiums = null;
        if (err && err.data && err.data.modelState) {
            for (var key in err.data.modelState) {
                var model = err.data.modelState[key];
                _.each(model, (state: string) => {
                    this.$log.debug(OfferControllerPrefix, "Calculation failed: " + state);
                });
            }
        }

        this.messages.push(new Message(MessageType.SVR_ERROR, "premiumCalculationParams", this.jsTranslations.getTranslation(Constants.DEFAULT_ERROR_NL), this.policy));
    });

}
public calculatePremiums(policy: Policy, selectedCoverageIndex : number): any {
    var uri = this.uriService.buildURI("Policy/Calculate");
    var data = {
        'policy': policy,
        'selectedCoverageIndex': selectedCoverageIndex
    };
    return this.$http.post<any>(uri, data);
}

Как решить эту проблему?

1 Ответ

0 голосов
/ 03 сентября 2018

Чтобы объединить две асинхронные операции, верните значения их .then методам:

function M1(data) {
    return $http.post(url1, data);
}

function M2(data) {
    return $http.post(url2, data);
}

Цепочка двух функций выглядит так:

function M1M2 () {

    var promise = M1(data);

    var promise2 = promise.then(function(data) {
       var data2 = fn(data);
       var m2Promise = M2(data2);
       return m2Promise;
    });

    return promise2;
}

Поскольку вызов метода обещания .then возвращает новое производное обещание, можно легко создать цепочку обещаний.

Можно создавать цепочки любой длины, и поскольку обещание может быть разрешено с помощью другого обещания (что приведет к дальнейшему отложению его разрешения), возможно приостановить / отложить разрешение обещаний в любой точке цепочки. Это позволяет реализовать мощные API.

Для получения дополнительной информации см. AngularJS $ q Справочник по API службы - обещания цепочки .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...