我有一些看起来像这样的node.js承诺代码:
function myFunc(data) {
Q(data).then(function(data) {
return getPromise1(globalVar).then(function(res1a) {
return getPromise2(JSON.parse(param2)).then(function(res2a) {
return doStuff();
}).then(function(res2b) {
return getPromise3(data).then(function(res3a) {
return getPromise4.then(function(res4a) {
// more stuff
})
})
})
})
})
})
如您所见,此代码不易读取。有更好的方法吗?
答案 0 :(得分:3)
如果您不需要同时获得所有结果,请停止处理回调等承诺:
function myFunc(data) {
Q(data).then(function(data) {
return getPromise1(globalVar);
}).then(function(res1a) {
return getPromise2(JSON.parse(param2));
}).then(function(res2a) {
return doStuff();
}).then(function(res2b) {
return getPromise3(data);
}).then(function(res3a) {
return getPromise4;
}).then(function(res4a) {
// more stuff
})
})
如果你这样做,那么你可以尝试coroutines给定生成器函数支持(Q可能有一些东西,但这里是Bluebird方式):
var myFunc = bluebird.coroutine(function* myFunc(data) {
var res1a = yield getPromise1(globalVar);
var res2a = yield getPromise2(JSON.parse(param2));
var res2b = yield doStuff();
var res3a = yield getPromise3(data);
var res4a = yield getPromise4;
// more stuff
})
function myFunc(data) {
var res1a = getPromise1(globalVar);
var res2a = res1a.then(function() {
yield getPromise2(JSON.parse(param2));
});
var res2b = res2a.then(function() {
// feel free to use res1a.value() here;
// you know that it has to have been resolved
doStuff();
});
// …
return res4a;
}
答案 1 :(得分:1)
在您的示例中,使用lambda表达式会有所帮助:
Q(data)
.then(data => getPromise1(globalVar)
.then(re1a => getPromise2(JSON.parse(param2)
等等。 没有嵌套和这种风格,它看起来不像回调地狱:)
答案 2 :(得分:1)
除了将数据参数与控制流参数分离之外,承诺的目标之一实际上是解决这个巨大的三角形代码块问题。
function myFunc(data) {
Q(data).then(function(data) {
return getPromise1(globalVar);
}).then(function(res1a) {
return getPromise2(JSON.parse(param2));
}).then(function(res2a) {
return doStuff();
}).then(function(res2b) {
return getPromise3(data);
}).then(function(res3a) {
return getPromise4;
}).then(function(res4a) {
// more stuff
})
}
现在,您需要嵌套一个promise的唯一原因是,如果您需要使用函数中的promise返回的数据,而不是紧跟在它之后。见下文:
doAsyncA().then(function(x) {
doAsyncB().then(function(y) {
doSyncUsingBothReturns(x, y);
})
})