2017-10-12 312 views
0

我真的很頭疼,試圖在使用for循環時使用異步/等待功能。我正在使用Node.js版本:v8.6.0異步/等待承諾麻煩 - Javascript/Nodejs

簡而言之,我試圖從數據庫中檢索許多行,然後將它們全部推送到數組並返回該數組。

我已經成功地完成了這個使用回調,但無法弄清楚如何使用異步/等待。

我當前使用的代碼回調,工程

function main(db) { 
    gatherDates(db, function(dates) { 
     console.log(dates); //successful 
    }); 
} 

function gatherDates(db, callback) { 
    const dates = []; 
    let today = getToday(); 

    dates.push(today); 

    let dateQuery = "SELECT date FROM event_dates"; 

    db.query(dateQuery, (err, newDates) => { 
     for(let row of newDates) { 
      dates.push(row.date); 
     } 
     callback(dates);    
    }); 
} 

失敗嘗試使用的代碼異步/ AWAIT

async function main(db) { 
    let dates = await gatherDates(db); 
    console.log(dates); //undefined or not all of the data 
} 

function gatherDates(db) { 
    const dates = []; 
    let today = getToday(); 

    dates.push(today); 

    let dateQuery = "SELECT date FROM event_dates"; 

    db.query(dateQuery, (err, newDates) => { 
     for(let row of newDates) { 
      dates.push(row.date); 
     } 
     return Promise.resolve(dates); 
    }); 
} 

我用Google搜索試圖找到一個解決方案,我有嘗試使用多個承諾,然後在最後調用return Promise.all(promises);但它沒有工作。我試過return new Promise((resolve, reject)=>resolve(dates))};。我曾看過Promise和異步/等待教程和例子,這些教程和例子通常適用於我,但是當涉及到循環訪問我所遇到問題的數據時。我知道有一些基本的東西我缺少,所以任何幫助表示讚賞。謝謝!

回答

3

的問題是,你想從db.query回調裏面return承諾,which can't work(甚至當你試圖用承諾的構造函數,你做到了裏面就有,與作爲Promise.resolve()效果相同)。 proper way to promisify就是用new Promise以外的,這樣你就可以從return它的外部函數中,並且只把resolve裏面的異步回調。

function query(sql) { 
    return new Promise((resolve, reject) { 
     db.query(sql, (err, res) => { 
      if (err) reject(err); 
      else resolve(res); 
     }); 
    }); 
} 

async function gatherDates(db) { 
    const dates = [getToday()]; 
    const newDates = await query("SELECT date FROM event_dates"); 
    for (let row of newDates) { 
     dates.push(row.date); 
    } 
    return dates; 
} 
+0

工作太棒了!現在我明白了許多好的承諾。謝謝 – nd510

0

您沒有正確地從你的異步函數返回一個Promise對象,這裏是解決方案:

function gatherDates(db) { 
    const dates = []; 
    let today = getToday(); 
    dates.push(today); 
    let dateQuery = "SELECT date FROM event_dates"; 

    return new Promise((resolve) => { 
     db.query(dateQuery, (err, newDates) => { 
      for(let row of newDates) { 
       dates.push(row.date); 
      } 
      resolve(dates); 
     }); 
    }); 
} 
+0

您還應該處理錯誤和異常。 – Bergi

+0

你絕對應該這樣做,但這不是他所要求的,我更願意以確切的所需行爲來回答。 –

+0

我不明白他在OP的要求中使用不良做法的問題。 – Bergi