有异步操作的承诺链没有按顺序执行
我发现其他人询问这个主题,但我没有能够让我的承诺链按顺序执行。有异步操作的承诺链没有按顺序执行
这里是正在发生的基本再现:
function firstMethod(){
dbHelper.executeQuery(queryParameters).then(result => {
if (result === whatIAmExpecting) {
return dbHelper.doDbOperation(secondQueryParameters)}
else {
throw new Error('An error occurred')
}})
.then(doFinalOperation())
.catch(error => {
})
}
在上面的代码doFinalOperation()的executeQuery后则()函数被调用之前被调用。
这里的executeQuery()的实现:
function executeQuery(parameter) {
return new Promise((resolve, reject) => {
const queryToExecute = `SELECT * FROM parameter`
return mySqlConnection.query(queryToExecute).then((result) => {
resolve(result)
}).catch(error => {
reject(error)
})
})
这里是的mySqlConnection.query方法的实现:
function query(queryString){
return new Promise((resolve, reject) =>
{
initConnection()
connection.connect()
require('bluebird').promisifyAll(connection)
return connection.queryAsync(queryString).then(function(results) {
connection.end();
resolve(results)
}).catch(error => {
reject(error)
})
})
好像我错误地实现了的executeQuery( ) 方法。 mySqlConnection.query中的数据库操作是不同步的,我可以看到这是承诺链以预期顺序停止发生的地方。
我的问题简而言之:如何使我的承诺链顺序执行,以及在前一个Promise调用resolve()或reject()之前如何停止执行then() )?
在此先感谢。
then
预期的功能,但是你不小心执行它,而不是传递。更改:
then(doFinalOperation())
有:
then(doFinalOperation)
现在会调用它(在适当的时间)的承诺实现,而不是 “你”。
如果你的函数需要参数传递,那么您可以
(1)使用bind
:
then(doFinalOperation.bind(null, parameterOne, parameterTwo, parameterThree))
(2)使用函数表达式
then(_ => doFinalOperation(parameterOne, parameterTwo, parameterThree))
感谢您的回复。你的解决方案可以解决这个问题,但是由于实际的'doFinalOperation()'需要参数,所以它必须被称为'doFinalOperation(parameterOne,parameterTwo,parameterThree)',所以我不能在不调用它的情况下传递它。但是,如果我将它实现为:'then(_ => {doFinalOperation(parameterOne,parameterTwo,parameterThree)})'那么它就可以工作。我已经将其他答案标记为正确,但我提出了你的答案。此解决方案也可能更好,因为它需要更少的嵌套 –
您可以使用'bind'绑定您的参数。查看更新。 – trincot
感谢您的提示。知道 –
无论您.then()
方法被调用的第一个异步操作...
应该是这样的:
function firstMethod(){
dbHelper.executeQuery(queryParameters).then(expectedResult => {
if (expectedResult === whatIAmExpecting) {
return dbHelper.doDbOperation(secondQueryParameters)}
.then(doFinalOperation())
.catch(error => {
};
}
else {
throw new Error('An error occurred')
}})
.catch(error => {
});
}
'doFinalOperation()'应该是'doFinalOperation'吗? –
我不知道,但在第一个代码块中它是'.then(doFinalOperation())'... –
感谢您的回复。您的解决方案可以解决问题 –
你有没有控制哪一个请求会首先被提供,所以除非你顺序地提出请求,否则你不能说它们将以什么顺序完成。我想知道为什么你会希望他们按特定的顺序完成。只要您没有数据依赖性,并行执行就是最省时的策略。但是,你肯定有你的理由。 –
要使事情顺序进行,只有在前一个承诺完成(或失败)后,才能启动下一个请求。这将会非常缓慢,并且首先会破坏承诺的目的(一个简单的顺序代码将完成相同的工作)。 –
感谢您的回复。只有在其他方法成功完成时才应调用doFinalOperation()方法,以便依赖于以前的操作,因此方法必须按顺序调用。为什么会让他们顺利击败承诺的目的呢? –