0

自周四以来,我一直被这个问题困扰,我无法弄清楚问题出在哪里。查看日志看起来 HTTP 请求在从数据库检索数据之前完成。我尝试了 async/await 的所有组合...

你们知道如何解决这个问题吗?

   app.get("/getData", (req, res) => {
    let data = oracledb.getConnection(
      {
        user: "hr",
        password: "hr",
        connectString: "localhost/user"
      },
      (err, connection) => {
        if (err) {
          console.error(err.message);
          return;
        }
        queries.getData(connection, 3);
      }
    );
    console.log('Arrives here:', data)
    res.send(data)
})

    const getData = (conn, id) => {
  const query = `SELECT * FROM SoapDataObject WHERE id = ${id}`;
  let result = conn.execute(query, (err, result)=> {
    if (err) {
      console.error(err.message);
      doRelease(conn);
      return;
    }
    // console.log(result.metaData);
    console.log(result.rows);
    doRelease(conn);
    return result.rows
  })
  return result;
};

控制台显示:

 REST API server started on: 3000
[1] Listening on port 8001
[1] WSDL available at http://localhost:8001/soapWs?wsdl
[1] Arrives here: undefined
[1] [ [ 3, '1010', 11, 11, 11, 11, 11, 2 ] ]
4

1 回答 1

0

很简单,问题就在这里:

let data = oracledb.getConnection(
      {
        user: "hr",
        password: "hr",
        connectString: "localhost/user"
      },
      (err, connection) => {
        if (err) {
          console.error(err.message);
          return;
        }
        queries.getData(connection, 3);
      }
    );
    console.log('Arrives here:', data)
    res.send(data)

请注意,无论 getData 的结果是什么,都不会在您获得return它之前返回。另外,在你的这个方法里面:

 const getData = (conn, id) => {
  const query = `SELECT * FROM SoapDataObject WHERE id = ${id}`;
  let result = conn.execute(query, (err, result)=> {
    if (err) {
      console.error(err.message);
      doRelease(conn);
      return;
    }
    // console.log(result.metaData);
    console.log(result.rows);
    doRelease(conn);
    return result.rows
  })
  return result;
};

请注意,您不能像在同步编程中那样从回调中返回对象。相反,在这两种方法中,您都试图返回无法以这种方式工作的回调方法的执行结果。您必须在回调范围内捕获结果,然后传播您的结果。(Johnathan建议的更优雅的解决方案是承诺调用 SQL 语句的方法,以便您可以返回“承诺”然后获取值。(请记住,async/await 只能与承诺一起使用,而不能与回调一起使用)。

一个示例实现因此变为(使用承诺):

app.get("/getData", (req, res) => {
    const dataPromise = new Promise((resolve, reject) => {
        oracledb.getConnection(
            {
                user: "hr",
                password: "hr",
                connectString: "localhost/user"
            },
            (err, connection) => {
                if (err) {
                    reject(error);
                    return;
                }
                queries.getData(connection, 3).then((response) => {
                    resolve(response)
                }).catch(qerror => {
                    reject(qerror);
                })
            }
        )
    });
    dataPromise.then((data) => {
        res.send(data);
    }).catch(error => {
        // Your error handling here
    })

})

const getData = (conn, id) => {
    return new Promise((resolve, reject) => {
        const query = `SELECT * FROM SoapDataObject WHERE id = ${id}`;
        conn.execute(query, (err, result) => {
            if (err) {
                doRelease(conn);
                reject(err);
                return;
            }
            doRelease(conn);
            resolve(result.rows);
        })
    });
};

或者,如果你想坚持回调:

app.get("/getData", (req, res) => {
    oracledb.getConnection(
        {
            user: "hr",
            password: "hr",
            connectString: "localhost/user"
        },
        (err, connection) => {
            if (err) {
                res.status(500).send(error);
                return;
            }
            const id = 3;
            const query = `SELECT * FROM SoapDataObject WHERE id = ${id}`;
            connection.execute(query, (qerr, result) => {
                if (qerr) {
                    doRelease(connection);
                    // Replace 500 with code of your choice
                    res.status(500).send(qerr);
                    return;
                }
                doRelease(connection);
                res.status(200).send(result.rows);
                return;
            })
        }
    );
});
于 2018-07-15T20:08:01.323 回答