承诺不能正常工作

时间:2016-05-10 18:27:04

标签: javascript mysql node.js express httprequest

我正在尝试使用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);
  });
});

1 个答案:

答案 0 :(得分:1)

这里发生的事情是你没有将所有异步代码绑定到承诺链。一旦我们将其转换为这样做,这应该可行。

首先让我们调用connection.query来返回一个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

技术对内部承诺进行排队