鍍金池/ 問答/數(shù)據(jù)庫  HTML/ node中map函數(shù)同步執(zhí)行

node中map函數(shù)同步執(zhí)行

看到這樣一句話 node中map()有一個特性:當其函數(shù)里面里面有回調(diào)它就變成異步;
我現(xiàn)在有一個這樣的一個函數(shù),遍歷數(shù)組從mongodb中找出想要的數(shù)據(jù)。

function save(arr) {
        let newArr = [];
        arr.map((item) => {
            Model.findOne({_id: item.id}, (err, data) => {
                newArr.push(data)
                //   do something
            })
        });
        console.log(newArr)
    }

我不是知道如何將這個函數(shù)改為同步的,我想要得到一個有數(shù)據(jù)的newArr,而不是一個空數(shù)組,
請指教!

回答
編輯回答
蝶戀花

async await 寫一個函數(shù)new promise你查詢到的值,然后用async定義save函數(shù),用await來獲取你resolve的值,在通過push生成數(shù)組。

2017年2月18日 18:37
編輯回答
雨萌萌

一日吸貓,終身吸貓。一旦異步,就不要試圖在其中混入同步的邏輯,這會極大地損失性能和造成各種問題。相反,你應該把所有同步的邏輯想辦法改為異步的,這是使用異步編程的最基本要求,也是對同步編程思維方式最大的一個挑戰(zhàn)。
異步的思維方式要求你找到合適的時間點觸發(fā)合適的事件。比如你的場景可以這樣理解:

  1. arr中的每個元素都可以找到一個對應的數(shù)據(jù)庫文檔
  2. 同時對數(shù)據(jù)庫發(fā)起n個請求,每個請求根據(jù)_id查詢對應的記錄(這就是map里面做的事情)
  3. 這些查詢得到結果是有先后的,但是誰先誰后不知道
  4. 你需要的時間節(jié)點是:當所有查詢都返回結果并pushnewArr之后再執(zhí)行后續(xù)操作

4的要求可以抽象為:同時執(zhí)行n個操作,如何在n個操作都完成后再執(zhí)行下面的操作。這是異步編程里面經(jīng)常遇到的問題。因為經(jīng)常遇到,所以肯定也已經(jīng)有解決方案了:

  1. Bluebird
  2. async

這兩個類庫請?zhí)粢粋€仔細學習,都可以解決你的問題。因為這是使用異步編程必須跨過的一關,必須要你自己理解,我在這里不給具體的答案,請先嘗試自己解決。

就事論事來說你的問題,無論是從效率還是便捷性上來說,其實你都做得太復雜了(當然不排除你是為了實驗目的)。從解決問題的角度來說,建議直接使用$in

function save(arr, callback) {
    let newArr = [];
    let ids = arr.map((item) => {
        return item.id
    });
    Model.find({_id: {$in: ids}}, (err, data) => {
        if (err) throw err;
        // data就是你需要的結果
        console.log(JSON.stringify(data));
        callback(err, data);
    })
}
2018年2月12日 22:32
編輯回答
萌小萌

你這個問題跟map沒關系
這樣試一下
mongoose 4 操作結果好像是promise

var save= async function (arr) {
    let newArr = [];
    for(var i=0;i<arr.length;i++){//await 不能嵌套在函數(shù)內(nèi)所以只能用for循環(huán)
        await Model.findOne({_id: arr[i].id}, (err, data) => {
            newArr.push(data)
        })
    }
    console.log(newArr)
};
2017年9月27日 08:32
編輯回答
萢萢糖

首先,你這樣用map和用forEach沒什么區(qū)別。

其次,對于異步并行操作,用promise.all,不要用單純的循環(huán)。

2018年5月25日 23:33