2016-05-11 40 views
1

在以下代码中,我试图将第一个和第二个查询的结果放入名为result的全局变量中。问题是Promise.all()未等待查询完成,并且在继续执行then()之前。如何正确使用Promise.all()和然后()与异步函数?

我该如何解决?

代码:

var result = {}; 
Promise.all([ 
    connection.query('SELECT * FROM analysis', 
    function(err, rows, fields) { 
     if (err) throw err; 
     result.analysis = rows; 
     console.log("query 1"); 
    }), 
    connection.query('SELECT * FROM analysis_description', 
    function(err, rows, fields) { 
     if (err) throw err; 
     result.analysis_description = rows; 
     console.log("query 2"); 
    }) 
]) 
.then(function(result){ 
    console.log(result); 
    console.log("result"); 
}); 

输出:

result 
query 1 
query 2 
+1

不'connection.query'返回一个承诺? –

+0

Promise.all接受一系列承诺。这些看起来不像承诺:-) –

+0

您需要“promisify”一个正常的异步回调函数,将其用作承诺:作为承诺是必须立即返回的值。有几种方法可以实现这一点。 – user2864740

回答

2

像评论说,你需要手动promisify的异步调用,:

queryAsync = query => new Promise((resolve, reject) => { 
    connection.query(query, (err, rows) => { 
    if(err) return reject(err) 
    resolve(rows) 
    }) 
}) 

或首选的方法是使用库如bluebird

connection = require('bluebird').promisifyAll(connection) 

和你的代码可以被修改为:

var result = {}; 
Promise.all([ 
    connection.queryAsync('SELECT * FROM analysis').then(rows => result.analysis = rows), 
    connection.queryAsync('SELECT * FROM analysis_description').then(rows => result.analysis_description = rows) 
]).then(function(result){ 
    console.log(result); 
    console.log("result"); 
}).catch(e => console.error(e)); 
+0

'catch()'会处理来自promisified函数的每个错误吗? – shadow00

+0

是的,它也会照顾到这一点 – mido

0

谢谢大家!就像所有人说的那样,这个问题在Promise.all()的错误参数中。这是更改后的代码。

代码:

Promise.promisifyAll(require("mysql/lib/Connection").prototype) 

var result = {}; 
Promise.all([ 
    connection.queryAsync('SELECT * FROM analysis') 
    .then(function(rows){ 
    console.log(rows); 
    result.analysis = rows; 
    }), 
    connection.queryAsync('SELECT * FROM analysis_description') 
    .then(function(rows){ 
    result.analysis_description = rows; 
    }) 
]) 
.then(function(){ 
    console.log(result); 
    console.log("result"); 
});