2015-11-14 21 views
3

我在Node.js中有一個問題,我建立了自己的模塊,來處理一種東西,在這個模塊中我有一個函數getList(),我可以得到一個輸入到我的配置。Node.js中的MySQL問題 - 獲取所有查詢

我的源代碼是這樣的:

var config = { 
    'limit' : 0 
}; 

var dict = []; 


exports.getList = function(db, conf) { 
    db.query("SELECT id, title FROM animal a " + (config.limit > 0 ? " LIMIT " + config.limit : ""), function(err, rows, fields) { 
     if(err) { 
      console.log(err); 
     } 

     for(var key in rows) { 
       var row = rows[key]; 
     // 
       dict.push({ 
        'title' : 'Buster', 
        'animal' : 'Dog', 
        'age' : '12', 
        'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200' 
       }); 
    }); 

    console.log(dict); 
    console.log(config); 

    return dict; 
} 

問題是,當我開始我的應用程序並第一次我把這個腳本的字典其空,第二次的從我的數據庫3排,每當我重新加載頁面時,它會再添加3個頁面。

我試圖找出我如何處理這個問題白茫茫一個明白的希望有人可以幫助我在這裏,非常感謝。

回答

2

你應該通過回調到db.query,或返回的承諾,而不是DIST,因爲db.query是async方法,您不能以同步方式調用異步方法。在過去,我們會使用回調,例如

exports.getList = function(db, conf, callback) { 
    db.query('', function (err, result) { 
    if(err) return callback(err); 
    callback(null, result); 
    }); 
} 

getList(db,conf, function(err, result) { 
    console.log(result); 
}); 

現在我想推薦使用promise。

exports.getList = function(db, conf) { 
    return new Promise(function(resolve, reject) { 
     db.query("SELECT id, title FROM animal a " + (conf.limit > 0 ? " LIMIT " + conf.limit : ""), function(err, rows, fields) { 
      if(err) { 
       reject(err); 
       return; 
      } 
      var dict = []; 
      for(var key in rows) { 
       var row = rows[key]; 
     // 
       dict.push({ 
        'title' : 'Buster', 
        'animal' : 'Dog', 
        'age' : '12', 
        'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200' 
       }); 
     }); 
     resolve(dict); 
    }); 

} 

getList(db,config).then(function(result) { 
    console.log(result); 
}).catch(function(e) { 
    console.log(e); 
}); 

,你也可以調用兩個查詢在parallal例如

Promise.all([getList1(db,config), getList2(db,config)]).then(function(result) { 
    console.log('result of getList1', result[0]); 
    console.log('result of getList2', result[1]); 
}); 

,並承諾,您可以使用ES6發生器co,調用異步方法在同步方式

var co = require('co'); 

co(function*() { 
    try { 
    var result = yield getList(db, conf); 
    // here is your result 
    } catch(e) { 
    console.log(e); 
    } 

}); 
+0

嗯,現在我真的是與會者..我來自PHP或其他沒有異步語言,你能解釋我什麼在這裏發生什麼,承諾什麼嗎? – ParisNakitaKejser

+0

我已經得到了現在工作的承諾,我現在需要修復的唯一事情是,它第一次打我的頁面(在我的應用程序之後)重新啓動,我得到一個錯誤成爲它的聲音沒有發現數據庫,如果我重新加載所有工作,所以一些工作不正常,我打錯了,我做錯了什麼?只是跟着你的信息。 – ParisNakitaKejser

+0

@ParisNakitaKejser我可能會錯過輸入'conf'到'config',我在'getList'中看不到任何問題,您可能需要向我展示更多代碼,問題可能出現在您的控制器中,當您將db傳遞給getList' – Sean

2

您是初始化dict一次,在功能之外。當你需要這個模塊時,這個調用只發生一次。

後來在函數中將新行推送給它 - 因此它會一直添加ip,因此不會在調用之間清除數組。

你應該的dict初始化移動到功能

編輯內:看到您的意見後,就在這裏多了一個(大)問題:您忽略的node.js中的異步特性

節點異步工作,這意味着它將一個接一個地運行db.query,您的兩個console.logreturn聲明,而不會等待結束之前。這意味着return語句可以在db.query和它的回調之前執行(可能會,因爲連接數據庫操作比兩個控制檯日誌慢)。

所以當你沒有初始化字典 - 你會得到每一次插入到它的結果先前調用的函數。一旦你清理它,你就會清空它,因爲它還沒有填滿。

解決方案不應該像這樣返回結果,而是建立你的函數,除了回調,並且在這個回調中返回結果(這種方式你可以控制何時調用這個回調函數,並且只有一次運行它有結果)

這是我會怎麼做它:

exports.getList = function(db, conf, callback) { 
    var dict = []; 
    db.query("SELECT id, title FROM animal a " + (config.limit > 0 ? " LIMIT " + config.limit : ""), function(err, rows, fields) { 
     if(err) { 
      console.log(err); 
     } 

     for(var key in rows) { 
       var row = rows[key]; 
     // 
       dict.push({ 
        'title' : 'Buster', 
        'animal' : 'Dog', 
        'age' : '12', 
        'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200' 
       }); 
     console.log(dict); 
     console.log(config); 
     callback(dict); // this will return the results to the calling function's callback 
    }); 

} 
+0

是的,我現在它,但是當我移動字典裏面的功能,我不能推它了。 – ParisNakitaKejser

+0

爲什麼不呢?無論如何,你可以在for循環之前加上'dict = [];' –

+0

是的,但是它完成的工作,當我做它它什麼都沒有返回時, – ParisNakitaKejser