如何进行条件承诺链接
How to do conditional promise chaining
我正在学习 promises/typescript/angular 并且我想有条件地链接 promise。
这是我方法的实际状态:
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 时遇到了同样的问题。
不只是在创建 promise 之后,而是在 if 之后放置 .then 是否正确?
是否有可能 .then 可能永远不会被调用,因为承诺已经完成?
可以按任何顺序将 promise 链接在一起,或者使用 ifs、循环等等。
如果您在已解决的承诺上调用 .then
,那么它会立即执行,所以这也很好。
then 不会被调用的唯一方法是承诺链从未解决或被拒绝。
正常的链接方式可能是 return 函数内的下一个对象。这往往比调用 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;
})
executePromiseModificationEvenement()
不需要延迟。传入一个绝对没有任何价值。相反,您应该查看 return 由函数内形成的承诺链 return 提供的承诺。调用函数只需要稍作改动。
直截了当地说,您的函数可以用一系列(条件)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
有机会改变状态。
就我个人而言,我认为稍后 执行测试 更合适(或无关紧要)。如果是这样,就可以无条件地构建 promise 链,并在内部执行所有测试,如果没有别的,那就更整洁了。
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()
});
}
});
}
});
}
我正在学习 promises/typescript/angular 并且我想有条件地链接 promise。
这是我方法的实际状态:
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 时遇到了同样的问题。
不只是在创建 promise 之后,而是在 if 之后放置 .then 是否正确?
是否有可能 .then 可能永远不会被调用,因为承诺已经完成?
可以按任何顺序将 promise 链接在一起,或者使用 ifs、循环等等。
如果您在已解决的承诺上调用 .then
,那么它会立即执行,所以这也很好。
then 不会被调用的唯一方法是承诺链从未解决或被拒绝。
正常的链接方式可能是 return 函数内的下一个对象。这往往比调用 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;
})
executePromiseModificationEvenement()
不需要延迟。传入一个绝对没有任何价值。相反,您应该查看 return 由函数内形成的承诺链 return 提供的承诺。调用函数只需要稍作改动。
直截了当地说,您的函数可以用一系列(条件)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
有机会改变状态。
就我个人而言,我认为稍后 执行测试 更合适(或无关紧要)。如果是这样,就可以无条件地构建 promise 链,并在内部执行所有测试,如果没有别的,那就更整洁了。
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()
});
}
});
}
});
}