iT邦幫忙

1

MongoDB存取採用Promise與async/await回傳是undefined

如題,
就算用了await語法,程序還是不會按照順序執行,

app.js

router.post('/getPersonallyQuestion', async (req,res,next)=>{
  const errQ = req.body;
  
  var err_temp;
  const errorQ = (errQ) => {
    return new Promise(async (resolve, reject) => {
      for (let i = 0; i < errQ.errQ.length; i += 1) {
        const result = await db.getDB().collection(collection).find({ pname: errQ.errQ[i] }).toArray();
        err_temp += JSON.stringify(result);
      }
      resolve(err_temp);
    });
  };
  reQ = errQ["errQ"].length;
  if(reQ != 0){ 
    err_temp = await errorQ(errQ)
    .then(err_temp => err_temp)
    .catch(err => res.status(500).send({ message: err }).end());
  }
  
  reQ = 4 - reQ;
  
  const dbCount = () => {
    return new Promise(async (resolve, reject) => {
      const result = await db.getDB().collection(collection).countDocuments({}, function(error, numOfDocs) {
        //console.log('I have '+numOfDocs+' documents in my collection');
        resolve(numOfDocs);
      });
    });
  };
  
dbDocumentCount = await dbCount();
var threeGroup = Math.floor( dbDocumentCount/3 );
var hml_temp;


const high = () => {
  return new Promise(async (resolve, reject) => {
    const result = await db.getDB().collection(collection).aggregate([
      { $sort : { total_number : -1 } },
      { $limit : threeGroup },
      { $sample: { size: 1 } }
  ]).toArray();
    console.log("high");
    console.log(result);
    resolve(result);
  });
};

const medium = () => {
  return new Promise(async (resolve, reject) => {
    const result = await db.getDB().collection(collection).aggregate([
      { $sort : { total_number : -1 } },
      { $skip : threeGroup },
      { $limit : threeGroup },
      { $sample: { size: 1 } }
  ]).toArray();
    console.log("medium");
    console.log(result);
    resolve(result);
  });
};


const low = () => {
  return new Promise(async (resolve, reject) => {
    const result = await db.getDB().collection(collection).aggregate([
      { $sort : { total_number : -1 } },
      { $skip : threeGroup+threeGroup },
      { $limit : threeGroup },
      { $sample: { size: 1 } }
  ]).toArray();
    console.log("low");
    console.log(result);
    resolve(result);
  });
};

const qList = () => {
  return new Promise(async (resolve, reject) => {
    for(let i=0; i<reQ; i++){
      console.log(reQ+"reQ");
      
      let j = random.getRandom(6); //1~6之間
      if( j >=1 && j <=3 ){
        let h_temp = await high()
        .then(h_temp => h_temp+hml_temp)
        .catch(err => res.status(500).send({ message: err }).end());
        console.log("hml_temp_high");
        console.log(hml_temp);
        
      }else if( j >=4 && j <=5 ){
        let m_temp = await medium()
        .then(m_temp => m_temp+hml_temp)
        .catch(err => res.status(500).send({ message: err }).end());
        console.log("hml_temp_medium");
        console.log(hml_temp);
        
      }else{
        let l_temp = await low()
        .then(l_temp => l_temp+hml_temp)
        .catch(err => res.status(500).send({ message: err }).end());
        console.log("hml_temp_low");
        console.log(hml_temp);
      }
      console.log( "In for---------hml_temp------------" );
      console.log( hml_temp );
    }
    resolve(hml_temp);
    console.log( "3---------hml_temp------------" );
    console.log( hml_temp );
  });  
};

// console.log(hml_temp);
console.log("1-----err_temp--------");
console.log(err_temp);
let problem = await JSON.stringify( qList() );

console.log("2-----problem--------");
console.log(problem);


});

出來的結果是

1-----err_temp--------
undefined[{"_id":"5d4596907cf65f4d8c47288e","pname":"snake","total_number":"668000000"}][{"_id":"5d4594ccf838a13138663474","pname":"wallet","total_number":"5090000000"}]
2reQ
2-----problem--------
{}
high
[
  {
    _id: 5d4596097cf65f4d8c472881,
    pname: 'crayon',
    total_number: '677000000'
  }
]
hml_temp_high
undefined
In for---------hml_temp------------
undefined
2reQ
high
[
  {
    _id: 5d4594ccf838a13138663474,
    pname: 'wallet',
    total_number: '5090000000'
  }
]
hml_temp_high
undefined
In for---------hml_temp------------
undefined
3---------hml_temp------------
undefined

懇請各位大大解答,謝謝

看更多先前的討論...收起先前的討論...
dragonH iT邦超人 6 級 ‧ 2019-08-07 20:26:37 檢舉
有沒有完整的 app.js 跟 database

太亂了 (*/ω\*)
RenZhou iT邦新手 5 級 ‧ 2019-08-07 20:31:54 檢舉
等等 都用promise了 怎麼還在async/await 直接在then內處理不難吧
dragonH iT邦超人 6 級 ‧ 2019-08-07 20:37:58 檢舉
看情況吧 我覺得他這個如果改用 then 會更亂

然後我建議沒必要全部都塞在 router 裡

把那些 function 拉出去應該會簡潔很多

也不要在你那些 function 直接用 req object

function 應該是 reject error 後

再丟給 router 處裡 req 的部分
p39212053 iT邦新手 5 級 ‧ 2019-08-07 21:25:42 檢舉
因為拉出去之後就不知道為甚麼抓不到資料了QQ,所以又拉回來,很抱歉真的很亂 (இ﹏இ`。),

這算是這部分完整的程式碼了,其他路由的功能只是很簡單的連接資料庫和抓取資料庫資料顯示到前端
dragonH iT邦超人 6 級 ‧ 2019-08-07 21:35:34 檢舉
那可以講解一下想要的輸入/輸出結果嗎 ╰(*°▽°*)╯

例如 hml_temp 裡面是什麼

會抓不到資料是因為你該給的參數沒給

例如 threegroup

你應該要寫成每個 function 都能獨立作業

不要依賴某個 function "內" 變數

最後在 router 裡組完結果送回前端

1 個回答

3
dragonH
iT邦超人 6 級 ‧ 2019-08-07 22:58:05
最佳解答
const errorQ = (errQ) => {
...
})
const dbCount = () => {
...
}
const high = (threeGroup) => {
...
}
const medium = (threeGroup) => {
...
}
const low = (threeGroup) => {
...
}
const qList = (reQ, threeGroup) => {
...
}

router.post('/getPersonallyQuestion', async (req, res) => {
    ...
    await errorQ(errQ)
    ...
    await dbCount();
    ...
    const problem = JSON.stringify(await qList(reQ, threeGroup));
    res.status(200).send({ problem }).end();
})

大概修一下

這樣 router 裡只需要組合各個 function 的結果

然後送回前端

看起來會比較簡潔

要改某個 function 也不會找不到

當然

最理想的

還是切成類似

controller + service + model

的架構

p39212053 iT邦新手 5 級 ‧ 2019-08-07 23:01:49 檢舉

(ง •̀ω•́)ง✧ 感謝 dragonH大 提點

我要發表回答

立即登入回答