使用不按顺序执行的异步操作的Promise链

时间:2017-07-30 16:33:20

标签: javascript node.js bluebird es6-promise node-mysql

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

以下是对正在发生的事情的基本再现:

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

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

提前致谢。

2 个答案:

答案 0 :(得分:2)

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

 then(doFinalOperation())

使用:

 then(doFinalOperation)

现在它将成为调用它的promise实现(在适当的时候),而不是"你"。

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

(1)使用bind

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

(2)使用函数表达式

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

答案 1 :(得分:0)

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