Javascript 处理嵌套承诺的最佳方式(蓝鸟)
我有下面的承诺链,它看起来很混乱(每个Javascript 处理嵌套承诺的最佳方式(蓝鸟),javascript,promise,bluebird,Javascript,Promise,Bluebird,我有下面的承诺链,它看起来很混乱(每个\u create*函数返回一个承诺): 我知道我可以使用一些Promise函数,比如all()和join(),但这些函数似乎同时运行,而我不能这样做,因为持久化到某些表需要来自先前持久化表的字段。我希望有一些方法可以让我做如下事情,但我似乎无法找到方法: Promise.all(_this._createExternalAccount(payment, t), _this._createExternalTransaction(externalAccount
\u create
*函数返回一个承诺):
我知道我可以使用一些Promise函数,比如all()
和join()
,但这些函数似乎同时运行,而我不能这样做,因为持久化到某些表需要来自先前持久化表的字段。我希望有一些方法可以让我做如下事情,但我似乎无法找到方法:
Promise.all(_this._createExternalAccount(payment, t), _this._createExternalTransaction(externalAccount, payment, t), _this._createAddress(externalAccount, payment, t))
.then(function(externalAccount, externalTransaction, address) {
// do logic
});
就个人而言,当依赖关系变得混乱时,我更喜欢以下方法:
var externalAccount = Promise.join(payment, t, createExternalAccount),
externalTransaction = Promise.join(externalAccount, payment, t, createExternalTransaction),
address = Promise.join(externalAccount, payment, t, createAddress),
transaction = Promise.join(address, payment, createTransaction),
gatewayTransaction = Promise.join(externalTransaction, transaction, payment, t, createGatewayTransaction);
让一切变得更干净,尽管这是一个风格的问题
如果您想在获得gatewayTransaction
的值(当然是异步的)后做些什么,您可以:
gatewayTransaction
.then(function (val) {
// do stuff
})
.catch(function (err) {
// do stuff
});
这里有一个微妙的陷阱,你应该注意。承诺的定义顺序不一定是函数的调用顺序。这就是依赖项的外观:
externalAccount -----> externalTransaction -----> gatewayTransaction
|--> address --> transaction --|
虽然这对性能有好处,但您可能希望使整个过程按顺序进行(就像回调金字塔一样)。在这种情况下,您可以编写:
var externalAccount = Promise.join(payment, t, createExternalAccount),
externalTransaction = Promise.join(externalAccount, payment, t, createExternalTransaction),
address = Promise.join(externalAccount, payment, t, externalTransaction, createAddress),
transaction = Promise.join(address, payment, createTransaction),
gatewayTransaction = Promise.join(externalTransaction, transaction, payment, t, createGatewayTransaction);
通过将
externalTransaction
添加到address
的依赖项中(即使不需要它的值),您可以强制它是连续的 我完全确定你在问什么,但是
var p = firstFunctionThatReturnsAPromise()
.then(secondFunctionThatReturnsAPromise)
.then(thirdFunctionThatReturnsAPromise)
.then(fourthFunctionThatReturnsAPromise)
你可以很容易地把它们套起来
function AOuterFunctionThatReturnsAPromise() {
var p = firstFunctionThatReturnsAPromise()
.then(secondFunctionThatReturnsAPromise)
.then(thirdFunctionThatReturnsAPromise)
.then(fourthFunctionThatReturnsAPromise);
return p;
};
现在,外部函数只是另一个返回承诺的函数,这意味着
可以应用与内部函数相同的模式
如果这些当然可以内联的话
var p = function() {
return new Promise(resolve, reject) {
DoSomethingAsync(function(err, result) {
if (err) {
reject();
} else {
resolve(result);
};
};
}).then(function() {
return new Promise(resolve, reject) {
DoSomethingAsync(function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
};
};
}).then(function() {
var err = DoSomethingNotAsync();
if (err) {
return Promise.reject(err);
} else {
return Promise.resolve();
}
});
等等您可能想探索链接:
p.then().then().then().then()
而不是嵌套。检查Bluebird.map()
您可以传递{concurrency:N}
,因此它一次只执行N
操作这肯定是我在讨论使用Gorgi和Petka向Bluebird添加联接时想到的。我觉得这是一个很好的风格很高兴听到,我真的很喜欢它。
var p = function() {
return new Promise(resolve, reject) {
DoSomethingAsync(function(err, result) {
if (err) {
reject();
} else {
resolve(result);
};
};
}).then(function() {
return new Promise(resolve, reject) {
DoSomethingAsync(function(err, result) {
if (err) {
reject(err);
} else {
resolve(result);
};
};
}).then(function() {
var err = DoSomethingNotAsync();
if (err) {
return Promise.reject(err);
} else {
return Promise.resolve();
}
});