2016-01-19 2 views
0

Я изучаю обещания/машинописные/угловые, и я хочу условно обезопасить себя.Как сделать условное объединение цепей

Это фактическое состояние моего метода:

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(); 
     }); 
    } 
} 

Я знаком в асинхронном/Await из C#, ни один из которых дает проблемы с условной цепочки, но у меня возникают проблемы в достижении того же с обещаниями.

Является ли это исправить, чтобы поставить .then не только после создания обещания, но после того, как если?

Возможно ли, что .then не может быть вызвано, потому что обещание уже закончено?

+2

Возможно, это было бы лучше для [CodeReview] (http://codereview.stackexchange.com/)? – Script47

+0

@ Script47 не совсем. OP хочет помочь добавить дополнительные функциональные возможности в свой код. Это будет Off-Topic в обзоре кода. – Kaz

+1

@ Zak OP фактически не задал вопрос или не заявил, что у него есть какие-либо проблемы, кроме того, что в заголовке, что звучит точно так же, как запрос обзора кода. – Alnitak

ответ

1

Это нормально, чтобы скреплять обещания вместе в любом порядке или использовать ifs, петли, что угодно.

Если вы позвоните по телефону .then по разрешенному обещанию, он будет выполняться мгновенно, так что это нормально.
Единственный способ, которым тогда не будет называться, - это то, что цепочка обещаний никогда не разрешается или не отклоняется.

Обычный способ соединения может состоять в том, чтобы вернуть следующий объект из функции. Это имеет тенденцию быть более аккуратным, чем вызов deferred.resolve().

E.g.

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

executePromiseModificationEvenement() не нуждается в Отложено. Нет никакой ценности при передаче. Вместо этого вы должны искать возвращение обещания, возвращенного цепочкой обещаний, сформированной внутри функции. Функция (ы) вызывающего абонента будет нуждаться только в незначительных изменениях.

Справедливо, ваша функция может быть переписана с помощью ряда (условных) 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; 
} 

Однако это может быть не лучшее решение.

Это может быть более подходящим для выполнения теста if(this.$scope.outlook) в точке, где this.$calendrier.Actions.modifierEvenement()... называется, при проведении расчетов цепи, а не в фазе цепи здания. Результат не обязательно будет таким же, потому что 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() 
        }); 
       } 
      }); 
     } 
    }); 
} 
Смежные вопросы