假设你有6个返回promises的方法,A(),B(),C(),D(),E(),F()和G()。
有些人在其他人拥有之前无法正常执行。例如,C()需要A()。 F()& E()需要C()。 B()需要A()和F()。 G()要求所有其他人都完整。
A().then(() => {
C().then(() => {
F().then(() => {
B();
});
E();
});
}).then(() => {
G();
});
D();
现在,说某些逻辑需要在影响其行为的其中几个函数之间运行。
A().then(() => {
let foop = this._service.getFoop();
C(foop).then((noop) => {
noop.forEach((n) => { n *= -1; });
F(noop).then((boop) => {
boop = boop.flatten();
B(foop, boop);
});
E('MonkeyWrench');
});
}).then(() => {
let glipglop = this._service.findGlip(this.LOCAL_GLOP_KEY);
G(glipglop, 42);
});
D();
然后,最重要的是,我们需要确保这些承诺能够捕获并处理错误。
A().then(() => {
let foop = this._service.getFoop();
C(foop).then((noop) => {
noop.forEach((n) => { n *= -1; });
F(noop).then((boop) => {
boop = boop.flatten();
B(foop, boop).catch((e) => {
this.handleErrorB(e);
});;
}).catch((e) => {
this.handleErrorF(e);
});
E('MonkeyWrench').catch((e) => {
this.handleErrorE(e);
});
}).catch((e) => {
this.handleErrorC(e);
});
}).then(() => {
let glipglop = _service.findGlip(this.LOCAL_GLOP_KEY);
G(glipglop, 42);
}).catch((e) => {
this.handleErrorA(e);
});
D().catch((e) => {
this.handleErrorD(e);
});
所以现在我们有一个完整的异步程序,由承诺组成 - 看起来像是一团糟。
采用这样的程序是什么方法,使其更容易阅读,以便未来的贡献者可以避免 潜入意大利面条代码?嵌套的promise结构本质上是混乱的,还是有可接受的协议 清理它并使其更具可读性?
我读了http://www.datchley.name/promise-patterns-anti-patterns/,它有一些很好的想法,比如使用promise.all([...]) 一次运行多个promise,但它没有包含任何支持在嵌套的promise调用之间使用逻辑。
提前感谢愿意为我传授一些智慧的人。
答案 0 :(得分:1)
Promise.all([…])
pattern 特别在promise调用之间使用逻辑 - 只需为新值创建一个新的承诺!
var a = A();
var foop = a.then(() => this._service.getFoop());
var c = foop.then(C);
var noop = c.then(x => x.map(n => n * -1));
var f = noop.then(F);
var boop = f.then(x => x.flatten());
var b = Promise.all([boop, foop]).spread(B);
var e = Promise.all([boop, foop]).then(() => E('MonkeyWrench'));
var d = D();
var glipglop = Promise.all([d, e, f]).then(() =>
this._service.findGlip(this.LOCAL_GLOP_KEY));
return Promise.all([gliplop, 42]).spread(G);
您可以将错误处理程序添加到相应的承诺中。
所以现在我们有一个完整的异步程序,由承诺组成 - 看起来像是一团糟。
这不是因为承诺,而是因为你的控制流是一团糟。也许这是固有的复杂性,但很可能并非如此。尝试将逻辑的一部分分解为单独的函数 - 这种策略无疑对嵌套的闭包模式更有效。还要尽量避免副作用 - 需要在并发控制流中的特定时间运行并且影响其他功能的逻辑总是很麻烦。相反,尽可能使其纯净,以处理仅在流向下传递的不可变值。