我找到了术语“The Ghost Promise” here ,这看起来像我的情况。
我有这样的代码:
return Q.Promise(function(resolve, reject) {
firstFunctionThatReturnPromise()
.then(function(firstResult) {
_check(firstResult) ? resolve(firstResult) : return secondFunctionThatReturnPromise();
})
.then(function(secondResult) {
console.log(secondResult);
return thirdFunctionThatReturnPromise(secondResult);
})
.then(function(thirdResult) {
resolve(thirdResult);
})
.catch(function(e) {
reject(e)
});
});
问题是,即使 _check
返回 true,它仍会继续执行 console.log
命令(导致 undefined
) .
如果 _check
返回 false,则一切正常。
所以我的问题是:
- 上述行为是否正常?
- 是否有更优雅的方式来处理这种情况?
更新 1: 许多人质疑为什么我使用 Q.Promise
而不是直接返回结果。这是因为这是一个通用函数,由其他函数共享。
// Usage in other functions
genericFunction()
.then(function(finalResult) {
doSomething(finalResult);
})
.catch(function(err) {
handleError(err);
});
最佳答案
首先,没有理由围绕这些做出新的 promise 。您的操作已经返回 promise ,因此它是 error prone anti-pattern用新的 promise 重新包装它们。
其次,正如其他人所说,.then()
处理程序有以下选择:
- 它可以返回一个结果,该结果将传递给下一个
.then()
处理程序。不返回任何东西将undefined
传递给下一个.then()
处理程序。 - 它可以返回一个 promise ,其解析值将传递给下一个
.then()
处理程序,或者拒绝值将传递给下一个拒绝处理程序。 - 它可以抛出 which 将拒绝当前的 promise。
除了拒绝之外,.then()
处理程序无法告诉 promise 链有条件地跳过一些后续的 .then()
处理程序。
因此,如果您想根据某些条件逻辑分支您的 promise,那么您实际上需要根据您的分支逻辑嵌套您的 .then()
处理程序:
a().then(function(result1) {
if (result1) {
return result1;
} else {
// b() is only executed here in this conditional
return b().then(...);
}
}).then(function(result2) {
// as long as no rejection, this is executed for both branches of the above conditional
// result2 will either be result1 or the resolved value of b()
// depending upon your conditional
})
因此,当您想要分支时,您可以创建一个新的嵌套链,让您可以根据条件分支控制发生的事情。
使用你的伪代码,它看起来像这样:
firstFunctionThatReturnPromise().then(function (firstResult) {
if (_check(firstResult)) {
return firstResult;
} else {
return secondFunctionThatReturnPromise().then(function (secondResult) {
console.log(secondResult);
return thirdFunctionThatReturnPromise(secondResult);
})
}
}).then(function (finalResult) {
console.log(finalResult);
return finalResult;
}).catch(function (err) {
console.log(err);
throw err;
});
即使这是在 genericFunction 中,您仍然可以只返回您已经拥有的 promise :
function genericFunction() {
return firstFunctionThatReturnPromise().then(function (firstResult) {
if (_check(firstResult)) {
return firstResult;
} else {
return secondFunctionThatReturnPromise().then(function (secondResult) {
console.log(secondResult);
return thirdFunctionThatReturnPromise(secondResult);
})
}
}).then(function (finalResult) {
console.log(finalResult);
return finalResult;
}).catch(function (err) {
console.log(err);
throw err;
});
}
// usage
genericFunction().then(...).catch(...)
关于javascript - 如何修复 promise 反模式 - Ghost Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38724752/