具有未按顺序执行的异步操作的承诺链

Promise chain with an asynchronous operation not executing in order

我发现其他人问过这个话题,但我无法让我的承诺链按顺序执行。

这里是对正在发生的事情的基本再现:

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 => {

        })
}

在上面的代码中,在调用 executeQuery() 之后的 then 函数之前调用了 doFinalOperation()。

这里是 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 中的数据库操作是异步的,我可以看到这是承诺链停止按预期顺序发生的地方。

我的问题简而言之:如何让我的承诺链按顺序执行,以及如何阻止 then() 方法在前一个方法之前执行Promise 调用了 resolve() 或 reject()?

提前致谢。

您的两个 .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 => {
      });
}

then 需要一个函数,但您不小心执行了它,而不是传递它。变化:

 then(doFinalOperation())

与:

 then(doFinalOperation)

现在(在适当的时间)调用它的是 promise 实现,而不是 "you"。

如果您的函数需要传递参数,那么您可以

(1) 使用 bind:

 then(doFinalOperation.bind(null, parameterOne, parameterTwo, parameterThree))

(2) 使用函数表达式

 then(_ => doFinalOperation(parameterOne, parameterTwo, parameterThree))