首页 文章

如何做有条件的承诺链

提问于
浏览
0

我正在学习promises / typescript / angular,我想有条件地链接承诺 .

这是我的方法的实际状态:

private executePromiseModificationEvenement<T>(edition: Models.CalendrierParametresModelEdition, modeCreation: boolean, deferred: ng.IDeferred<T>) {
    var promise: ng.IPromise<Object>;

    //Step1
    if (modeCreation) {
        promise = this.$calendrier.Actions.enregistrerEvenementOutlook(edition);
    } else {
        promise = this.$calendrier.Actions.modifierEvenementOutlook(edition);
    }

    if (this.$scope.outlook) {
        promise.then((x) => {
            if (x != '') edition.idOutlook = x.toString();;
            return deferred.resolve();
        }, (x) => {
            return deferred.reject();
        });
    } else {
        //Step2
        promise.then((x) => {
            if (x != '') edition.idOutlook = x.toString();
            return this.$calendrier.Actions.modifierEvenement(edition);
        }, (x) => {
            //Ajout MessageBox message error
            return this.$calendrier.Actions.modifierEvenement(edition);
        })
        //Step3
        .then((x) => {
            if (edition.opportunite != null) this.$rootScope.$broadcast("pushEchangeOpportunite", { idOpportunite: parseInt(edition.opportunite), action: 2, IdContact: edition.id, Libelle: edition.title, StartDate: moment(edition.start).toDate() });
            return deferred.resolve();
        }, (x) => {
            return deferred.reject();
        });
    }
}

我熟悉C#的async / await,它们都没有给条件链接带来问题,但是我很难用promises实现同样的功能 .

是不是在创建承诺之后但在_1444035之后放置 .then 是否正确?

是否可能永远不会调用 .then 因为承诺已经完成了?

2 回答

  • 1

    将promises以任何顺序链接在一起或使用ifs,循环等等都可以 .

    如果你在已解决的承诺上调用 .then ,它会立即执行,所以也没关系 .
    如果承诺链永远不会被解决或被拒绝,那么不会被调用的唯一方法就是这样 .

    正常的链接方式可能是从函数中返回下一个对象 . 这比调用 deferred.resolve() 更整洁 .

    例如 .

    var promise = this.$calendrier.Actions.enregistrerEvenementOutlook(edition);
    promise = promise.then(function (x) {
        return 2 * x;
    })
    promise = promise.then(function (x) {
        return 2 * x;
    })
    

    要么

    var promise =
        this.$calendrier.Actions.enregistrerEvenementOutlook(edition)
        .then(function (x) {
            return 2 * x;
        })
        .then(function (x) {
            return 2 * x;
        })
    
  • 1

    传递一个绝对没有 Value . 相反,你应该寻找返回由函数中形成的promise链返回的promise . 呼叫者功能只需要稍作改动即可 .

    直截了当地,您的函数可以用一系列(条件) promise = promise.then(...) 语句重写,最终 return promise . 一些代码重复也可以解决 .

    private executePromiseModificationEvenement<T>(edition: Models.CalendrierParametresModelEdition, modeCreation: boolean<T>) {
        var promise: ng.IPromise<Object>;
        promise = modeCreation ?
            this.$calendrier.Actions.enregistrerEvenementOutlook(edition) :
            this.$calendrier.Actions.modifierEvenementOutlook(edition);
    
        promise = promise.then((x) => {
            if (x != '') {
                edition.idOutlook = x.toString();
            }
        });
    
        if (!this.$scope.outlook) {
            promise = promise.then(() => {
                return this.$calendrier.Actions.modifierEvenement(edition);
            }, () => {
                return this.$calendrier.Actions.modifierEvenement(edition);
            })
            .then((x) => {
                if (edition.opportunite != null) {
                    this.$rootScope.$broadcast("pushEchangeOpportunite", {
                        idOpportunite: parseInt(edition.opportunite), 
                        action: 2, 
                        IdContact: edition.id, 
                        Libelle: edition.title, 
                        StartDate: moment(edition.start).toDate() 
                    }); 
                }
            });
        }
        return promise;
    }
    

    但是,这可能不是最好的解决方案 .

    在链式结算期间而不是在链构建期间,在调用 this.$calendrier.Actions.modifierEvenement()... 的位置执行 if(this.$scope.outlook) 测试可能更合适 . 结果不一定相同,因为 this.$scope.outlook 将有机会改变状态 .

    就个人而言,我猜测以后执行测试更合适(或无关紧要) . 如果是这样,可以无条件地构建承诺链,并且内部执行所有测试,如果没有别的话,则更加整洁 .

    private executePromiseModificationEvenement<T>(edition: Models.CalendrierParametresModelEdition, modeCreation: boolean<T>) {
        return (modeCreation ? 
            this.$calendrier.Actions.enregistrerEvenementOutlook(edition) :
            this.$calendrier.Actions.modifierEvenementOutlook(edition))
        .then((x) => {
            if (x != '') {
                edition.idOutlook = x.toString();
            }
        })
        .catch((x) => { return x; }) // this mid-chain-error-recovery line is rather odd but consistent with the original code. It may be better placed one step earlier.
        .then(() => {
            if (!this.$scope.outlook) {
                return this.$calendrier.Actions.modifierEvenement(edition)
                .then(() => {
                    if (edition.opportunite != null) {
                        this.$rootScope.$broadcast("pushEchangeOpportunite", {
                            'idOpportunite': parseInt(edition.opportunite),
                            'action': 2,
                            'IdContact': edition.id,
                            'Libelle': edition.title,
                            'StartDate': moment(edition.start).toDate()
                        }); 
                    }
                });
            }
        });
    }
    

相关问题