2016-11-24 42 views
0

如何使用node.js中的ES6原生承諾調用查詢?以下是代碼。在node.js中使用ES6承諾返回空響應

let arr= []; 
    conn.query('select * from table1', (err, b) => { 
    for (let i = 0; i < b.length; i++) { 
     console.log(b[i]["id"]) 
     let promiseGetData = new Promise((resolve, reject) => { 
      conn.query('select * from table2 where id = ?', [b[i]["id"]], (err, ce) => { 
       if (err) { 
        const response = { 
         statusCode: 500, 
         body: JSON.stringify({ 
          message: err 
         }), 
        } 
        reject(response); 
       } else { 
        if (ce.length != 0) { 
         resolve(ce); 
        } 
       } 
      }); 
     }); 

     promiseGetData .then((data) => { 
      b[i]['data'] = data; 
      arr.push(b[i]) 
     }).catch((err) => { 
      console.log(err); 
     }); 
    } 
console.log(b) 
    }) 

我看到一個空的響應,當我做console.log(b)。我不知道我是否以正確的方式使用了承諾,我認爲對於第一次查詢,我也應該在承諾中執行。任何幫助都非常感謝

+0

您是否考慮過ce.length == 0並且沒有錯誤的情況? –

+0

@GrantPark是的,我已經檢查沒有錯誤,實際上我已經在第二個查詢之前放置了console.log,之後我可以看到一個日誌但沒有查詢數據,但是我仍然會再次檢查該情況。 length == 0 –

+0

在這種情況下,還要在第二個查詢中放置一個console.log,看看是否運行。 –

回答

0

您從console.log(b)得到空響應,因爲查詢數據庫的承諾沒有完成。你必須等到他們完成才能得到完整的結果。

樣品:

let arr = []; 
conn.query('select * from table1', (err, b) => { 

    var promiseArr = []; 

    for (let i = 0; i < b.length; i++) { 
     let promiseGetData = new Promise((resolve, reject) => { 
      conn.query('select * from table2 where id = ?', [b[i]["id"]], (err, ce) => { 
       if (err) { 
        const response = { 
         statusCode: 500, 
         body: JSON.stringify({ 
          message: err 
         }), 
        } 
        reject(response); 
       } else { 
        if (ce.length != 0) { 
         resolve(ce); 
        } 
       } 
      }); 
     }); 

      promiseArr.push(promiseGetData); 
    } 

    Promise.all(promiseArr).then((resultArr) => { 
     //resultArr is all the resolved value returned from the promise in promiseArr 
     for (let i = 0; i < resultArr.length; i++) { 
      b[i]['data'] = resultArr[i]; 
      arr.push(b[i]); 
     } 
    }).then(() => { 
     console.log(arr); 
    }).catch((err) => { 
     //if any promise throw/reject with error, it will go here directly 
      console.log(err); 
    }); 
}) 

編輯: 編號:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

+0

感謝它的工作:) –

+0

我有一個問題應該第一個查詢也承諾嗎? –

+0

是的,你應該。對整個應用程序使用承諾或回調是一個很好的做法,但不能同時支持更好的代碼管理和可讀性。其實來自@drinchev的示例代碼非常乾淨且有幫助。檢查一下,如果你能理解它。 – iKoala

2

結束語一個基於異步回調函數爲一個承諾被稱爲Promisifying

當然你也可以使用一個庫,但基本上它的作用是:

const queryAsPromise = function(...args) { 
    return new Promise(function(resolve, reject) { 
     try { 
      conn.query(...args, function(error, result) { 
       if (error) { 
        reject(error); 
       } else { 
        resolve(result); 
       } 
      }); 
     } catch(error) { 
      reject(error); 
     } 
    }) 
}); 

通過這樣做一次,你會保持你的代碼幹,你可以隨時使用這個承諾現在進行查詢:

queryAsPromise('select * from table1') 
    .then(result => { 
      return Promise.all(
       result.map(b => { 
       return queryAsPromise('select * from table2 where id = ?', b["id"]) 
          .then(data => b["data"] = data) 
       }) 
     ) 
    ) 
    .catch(err => res.send(500)) 
    .then(console.log) 
+0

你忘了處理傳遞給查詢中的參數例:) – iKoala

+0

啊,好抓! :d – drinchev