2016-05-11 77 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"); 
});