【问题标题】:Promise not working properly承诺不能正常工作
【发布时间】:2016-09-05 21:17:17
【问题描述】:

我正在尝试使用 MySql 进行嵌套查询,将结果放入变量中并通过 http 发送,但程序始终在查询完成之前运行 console.log("test 2:"+rpsData);。我已经尝试过this,但仍然遇到同样的问题。

const express = require('express')  
const app = express()

const mysql = require('mysql');
const Connection = require('mysql/lib/Connection');
const Promise = require('bluebird');

Promise.promisifyAll([
    Connection
]);

const connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : 'root123',
  database : 'mygallery'
});
app.get('/posts', function(request, response) {
    var rpsData;
  connection.connectAsync()
  .then(function() {
    connection.query('SELECT * FROM post WHERE approved = 1', function(err, rows, fields) {
      if (err) throw err;
      rpsData = rows;
      for (var i in rows) {
        connection.query('SELECT * FROM image WHERE postCode = ?', [rpsData[i].postCode], function(err, rows, fields) {
          if (err) throw err;
          rpsData[i].image = rows;
          console.log("test 1:"+rpsData);
        });
      }
    });
  })
  .then(function() {
    response.send(rpsData);
    console.log("test 2:"+rpsData);
  })
  .catch(function(error) {
    console.error('Connection error.', error);
  });
});

【问题讨论】:

    标签: javascript mysql node.js express httprequest


    【解决方案1】:

    这里发生的情况是,您没有将所有异步代码片段都绑定到 Promise 链。一旦我们将其转换为这样做,这应该可以工作。

    首先让我们包装对connection.query 的调用以返回一个承诺。然后我们必须返回生成的 Promise 以将其附加到外部 Promise 链。

    如果你不返回一个 Promise,它就不会知道它必须等待你的代码完成执行,并将继续执行外部 Promise 上的下一个 .then() 语句(来自connection.connectAsync) ;

    您需要对内部查询应用相同的处理。

    示例代码:

    app.get('/posts', function(request, response) {
      connection.connectAsync()
      .then(function() {
        return new Promise(function(resolve, reject) {
          connection.query('SELECT * FROM post WHERE approved = 1', function(err, rows, fields) {
            if (err) reject(err);
            resolve(rows.reduce(function(accumulator, current) {
              return accumulator.then(function(rpsData){
                return new Promise(function(resolve, reject){
                  connection.query('SELECT * FROM image WHERE postCode = ?', [current.postCode], function(err, rows, fields) {
                    if (err) reject(err);
                    current.image = rows;
                    console.log("test 1:"+rpsData);
                    resolve(rpsData);
                  });
                });
              });
            }, Promise.resolve(rows)));
          });
        });
      })
      .then(function(rpsData) {
        response.send(rpsData);
        console.log("test 2:"+rpsData);
      })
      .catch(function(error) {
        console.error('Connection error.', error);
      });
    });
    

    我正在使用技术I describe here 对内部承诺进行排队

    【讨论】:

    • 感谢您的回答!现在response.send(rpsData) 正在通过 HTTP 发送消息,但没有来自第二个查询的数据。我应该在第二个查询中添加另一个return new Promise(function(resolve,reject) { ... }) 吗?
    • @shadow00 哎呀!我犯了一个愚蠢的错误。请给我一点时间来解决它。
    • @shadow00 试试看
    • resolve(rpsData) 没有等待第二个查询完成。
    • 有没有办法只在每次查询完成后才调用resolve?
    猜你喜欢
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    相关资源
    最近更新 更多