4 回答
TA贡献1836条经验 获得超13个赞
打破链条
当您需要访问链中的中间值时,您应该将链条拆分成您需要的那些单件。而不是附加一个回调并以某种方式尝试多次使用其参数,将多个回调附加到同一个承诺 - 无论您需要结果值。不要忘记,承诺只代表(代理)未来的价值!接下来,在线性链中从另一个派生一个承诺,使用库提供给您的promise组合器来构建结果值。
这将导致非常简单的控制流程,清晰的功能组合,因此易于模块化。
function getExample() {
var a = promiseA(…);
var b = a.then(function(resultA) {
// some processing
return promiseB(…);
});
return Promise.all([a, b]).then(function([resultA, resultB]) {
// more processing
return // something using both resultA and resultB
});
}
Promise.all
在ES5中只有ES6可用的回调中的参数解构代替,在ES5中,then
调用将被许多promise库(Q,Bluebird,when,...)提供的漂亮的辅助方法取代:.spread(function(resultA, resultB) { …
。
Bluebird还具有专用join
功能,可以用更简单(更高效)的构造替换Promise.all
+ spread
组合:
…return Promise.join(a, b, function(resultA, resultB) { … });
TA贡献1770条经验 获得超3个赞
同步检查
将promises-for-later-needed-values分配给变量,然后通过同步检查获取它们的值。该示例使用bluebird的.value()
方法,但许多库提供类似的方法。
function getExample() { var a = promiseA(…); return a.then(function() { // some processing return promiseB(…); }).then(function(resultB) { // a is guaranteed to be fulfilled here so we can just retrieve its // value synchronously var aValue = a.value(); });}
这可以用于任意数量的值:
function getExample() { var a = promiseA(…); var b = a.then(function() { return promiseB(…) }); var c = b.then(function() { return promiseC(…); }); var d = c.then(function() { return promiseD(…); }); return d.then(function() { return a.value() + b.value() + c.value() + d.value(); });}
TA贡献2003条经验 获得超2个赞
嵌套(和)闭包
使用闭包来维护变量的范围(在我们的例子中,成功的回调函数参数)是自然的JavaScript解决方案。有了promises,我们可以任意地嵌套和压缩 .then()
回调 - 它们在语义上是等价的,除了内部的范围。
function getExample() { return promiseA(…).then(function(resultA) { // some processing return promiseB(…).then(function(resultB) { // more processing return // something using both resultA and resultB; }); });}
当然,这是建立一个缩进金字塔。如果缩进变得太大,你仍然可以使用旧工具来对抗厄运的金字塔:模块化,使用额外的命名函数,并在不再需要变量时立即压缩承诺链。
理论上,你总是可以避免两个以上的嵌套级别(通过使所有闭包显式化),在实践中使用尽可能多的合理。
function getExample() { // preprocessing return promiseA(…).then(makeAhandler(…));}function makeAhandler(…) return function(resultA) { // some processing return promiseB(…).then(makeBhandler(resultA, …)); };}function makeBhandler(resultA, …) { return function(resultB) { // more processing return // anything that uses the variables in scope };}
您还可以使用辅助功能对于这种局部的应用,如_.partial
从下划线 / lodash或本地.bind()
方法,进一步减少缩进:
function getExample() { // preprocessing return promiseA(…).then(handlerA);}function handlerA(resultA) { // some processing return promiseB(…).then(handlerB.bind(null, resultA));}function handlerB(resultA, resultB) { // more processing return // anything that uses resultA and resultB}
添加回答
举报