【问题标题】:Returned array has undefined value返回的数组具有未定义的值
【发布时间】:2020-09-15 07:41:24
【问题描述】:

我正在尝试通过 async/await 返回一个数组:

        app.get('/users/article/feed',checkAuthenticated,async (request,response)=>{
           try{
             function executor(){
                let articleArray=[]

                const sql="SELECT noOfArticles FROM Articles WHERE id=?"
                db.query(sql,[request.user.id], (err,result)=>{
                  if(err) throw err
                  let noOfArticles=result[0].noOfArticles
                   for(let i=1;i<=noOfArticles;i++){
                     const sql1="SELECT ?? FROM Articles WHERE id=?"
                     let index='article'+i
                     db.query(sql1,[index,request.user.id],(err,result)=>{
                       if(err) throw err
                       articleArray.push(result[0][index])
                       if(articleArray.length===noOfArticles){
                         console.log(articleArray);      //here the array is printed as expected
                         return articleArray;
                  }
             })

            }

           })
          }
          const resultArray= await executor();
          console.log(resultArray);            //here the array is undefined
          response.render('viewArticles');

    }    catch(e){
          console.log(e);
      }

     })

resultArray 始终未定义。 我知道这是一个非常古老的问题。我尝试检查 Stack Overflow 中的所有其他答案,但对此我感到很困惑。我是 js 的新手,所以我无法正确理解它。我该如何解决这个问题?

【问题讨论】:

  • executor 正在使用基于回调的 API 并且不返回 Promise。 db.query 是否有基于 Promise 的替代方案?

标签: node.js express async-await


【解决方案1】:

当您返回 articleArray 时,您并不是从 executor 函数中返回它。相反,您从传递给 db.query 函数的回调中返回它。 () =&gt; {} 语法基本上是 function() {} 的简写(尽管存在超出此答案范围的差异)。

也许这样的事情可能会有所帮助(请注意,我删除了 try catch,因为我认为此类日志记录应该在 express 的中间件级别完成,您似乎正在使用它):

app.get('/users/article/feed', checkAuthenticated, async (request, response) => {
    return new Promise((resolve, reject) => {
        let articleArray = []

        const sql = "SELECT noOfArticles FROM Articles WHERE id=?"
        db.query(sql, [request.user.id], (err, result) => {
            if (err) reject(err)
            let noOfArticles = result[0].noOfArticles
            for (let i = 1; i <= noOfArticles; i++) {
                const sql1 = "SELECT ?? FROM Articles WHERE id=?"
                let index = 'article' + i
                db.query(sql1, [index, request.user.id], (err, result) => {
                    if (err) reject(err); // reject the promise if there is an error
                    articleArray.push(result[0][index])
                    if (articleArray.length === noOfArticles) {
                        console.log(articleArray);
                        resolve(articleArray); // resolve the promise with the value we want
                    }
                })
            }
        })
    })
})

【讨论】:

    【解决方案2】:

    您正在从回调函数内部返回,由于executor 不会等待您的查询响应,因此该回调函数将不起作用。而是返回一个 Promise。

    function executor() {
        return new Promise((resolve,reject) => {
            let articleArray = [];
    
            const sql = "SELECT noOfArticles FROM Articles WHERE id=?";
            db.query(sql, [request.user.id], (err, result) => {
                if (err) return reject(err);
                let noOfArticles = result[0].noOfArticles;
                for (let i = 1; i <= noOfArticles; i++) {
                    const sql1 = "SELECT ?? FROM Articles WHERE id=?";
                    let index = "article" + i;
                    db.query(sql1, [index, request.user.id], (err, result) => {
                        if (err) return reject(err);
                        articleArray.push(result[0][index]);
                        if (articleArray.length === noOfArticles) {
                            console.log(articleArray); //here the array is printed as expected
                            return resolve(articleArray);
                        }
                    });
                }
            });
        })
    }
    

    【讨论】:

      【解决方案3】:

      如果你使你正在调用的函数异步,它会返回一些结果吗?

      async function executor(){
                  let articleArray=[]
      
                  const sql="SELECT noOfArticles FROM Articles WHERE id=?"
                  db.query(sql,[request.user.id], (err,result)=>{
                    if(err) throw err
                    let noOfArticles=result[0].noOfArticles
                     for(let i=1;i<=noOfArticles;i++){
                       const sql1="SELECT ?? FROM Articles WHERE id=?"
                       let index='article'+i
                       db.query(sql1,[index,request.user.id],(err,result)=>{
                         if(err) throw err
                         articleArray.push(result[0][index])
                         if(articleArray.length===noOfArticles){
                           console.log(articleArray);      //here the array is printed as expected
                           return articleArray;
                    }
               })
      
              }
      
             })
            }
      

      【讨论】:

      • 不,它不返回任何值。控制台语句记录为 Promise {undefined}
      • 我建议将对象打印到控制台,因为您的代码通过该函数工作。例如,在函数开始时,我会执行 console.log(req.user.id)。然后在第一个 db.query 之后,我会执行 console.log(result)。跟踪它,直到找到没有返回结果的原因。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      相关资源
      最近更新 更多