【问题标题】:Implementing node.js call back to get result实现 node.js 回调以获取结果
【发布时间】:2018-04-01 04:16:19
【问题描述】:

我是 node.js 的初学者,所以如果我的问题很愚蠢,请原谅。实际上我正在尝试从 mongodb 获取一些结果并打印它们,但我无法获得所需的输出。

代码:

MongoClient.connect(url,function(err,db){
               if(err) throw err;

            var list=()=>{
                var arr=[]
                var blQ={blocked_user:data.tag_search_mail} 

                 db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{

                         for(let i=0;i<res.length;i++){
                             arr.push(res[i]["blocker"])
                         }

                   });  
                 return arr  
            }
            var showList=(callback)=>{
               callback()
            }
            console.log(showList(list))//It's giving undefined
          // I wonder how can I print the returned array

建议后我尝试了什么:

var list = (callback) => {
                var arr=[]

                    var blQ={blocked_user:data.tag_search_mail} 

                      db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{

                              for(let i=0;i<res.length;i++){
                                  arr.push(res[i]["blocker"])
                              }
                              callback(arr);    
                        });  

            }

            list((arr) => {
                console.log(arr);
            })

【问题讨论】:

    标签: node.js callback


    【解决方案1】:

    建议您使用the node.js native interface for mongodb 内置的promise 接口,而不是手动回调。

    如果您想将其放入一个函数中并返回结果并在完成后关闭数据库,那么您可以执行以下操作并从您的函数中返回一个调用者将使用的承诺。

    function getBlocked(data) {
        let openDb;
    
        close() {
            if (openDb) {
                openDb.close().catch(err => {
                    console.log("Error closing db: ", err);
                })
            }
        }
    
        return MongoClient.connect(url).then(db => {
            openDb = db;
            const blQ = {blocked_user:data.tag_search_mail};
            return db.collection("block_list").find(blQ,{"_id":0}).toArray();
        }).then(results => {
            let blocked = results.map(item => item.blocker);
            close();
            return blocked;     // make this the resolved value of the promise
        }).catch(err => {
            close();
            throw err;          // rethrow to keep the promise rejected
        })
    }
    
    // usage
    getBlocked(data).then(blocked => {
        // use blocked array here
    }).catch(err => {
        // handle error here
    });
    

    【讨论】:

    • 先生,感谢您的回答,但我仍然收到 [ ]
    • @NikhilKumar - 在哪里获取[]?您可以使用结果的唯一位置是在 .then() 处理程序内。这是异步代码。您必须对其进行编码并按原样使用它。
    • 我在 .then() 处理程序中得到 []
    • @NikhilKumar - 我必须查看您的确切代码才能帮助您调试它。
    • 先生,我正在使用您给定的代码this
    【解决方案2】:

    我建议使用 Mongoose,这是一个可以与 MongoDB 顺畅交互的 Node 模块。如果您有兴趣,这里是文档:http://mongoosejs.com/

    但是,要回答您的问题...

    您的代码目前的问题是showList 函数实际上并没有返回任何内容。这是你想要的:

    var list = (callback) => {
        // query mongodb here
        callback(arr);
    }
    
    list((arr) => {
        console.log(arr);
    });
    

    list 接受一个函数,最终在完成对 MongoDB 的查询时调用该函数。它将传入arr 对象。因此,当您稍后调用list 时,您传入一个接收arr 对象的函数,然后调用console.log(arr) 来打印结果。祝你好运!

    【讨论】:

    • 先生,感谢您的出色回答,但由于 db.collection() 是一个异步函数,这就是为什么我得到结果为 [] 所以你能帮我解决这个问题
    • 那么你所要做的就是调用 db.collection() 异步函数内部的回调函数。不幸的是,我不知道如何使 MongoDB 调用同步。
    • 先生,请检查编辑我什至在 db.collection 中添加了 callback() 但错误没有改变
    • 您能在 db.collection() 中执行console.log(arr) 以查看打印的内容吗?除非 MongoDB 查询本身存在问题,否则代码看起来应该可以工作。
    • 不,实际上发生的事情是我在 for 循环中得到了结果,这意味着查询很好,但我没有从循环中得到结果
    【解决方案3】:
    var list =() => {
    let arr =[];
    for(let a =0 ; a< 20; a++)
    arr.push(a);
    return arr;
    }
    
    var show = (callback) => {
    return callback()}
    
    console.log("123",show(list));
    

    输出::123 (20) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16、17、18、19]

    尝试在调用回调函数之前只添加一个return语句,并将列表函数的return语句添加到数据库块中。这可能会解决您的问题。

    MongoClient.connect(url,function(err,db){
               if(err) throw err;
    
            var list=(done)=>{
                var arr=[]
                var blQ={blocked_user:data.tag_search_mail} 
    
                 db.collection("block_list").find(blQ,{"_id":0}).toArray((err,res)=>{
    
                         for(let i=0;i<res.length;i++){
                             arr.push(res[i]["blocker"])
                         }
                    if(err) done(err);
                    else done(null,arr);
                   });  
    
            }
            var showList=(callback)=>{
               callback((err, result) => {
                if(err) console.log(err);
                else console.log(result):
    })
            }
            showList(list);
    

    【讨论】:

    • 这段代码是异步的。您不能直接返回结果并期望它在那里。
    • @jfriend00 只有在数据库内部执行for循环时才会返回arr。用户代码中有两件事不正确,首先他在数据库块之外返回“arr”,这是异步的,甚至在数据库执行结束之前也会被调用。其次,他没有返回来自回调函数的结果。
    • list() 函数早已返回。您的 return arr 正在从 DB 回调返回,该回调只是返回到数据库的某处,与 list() 函数的返回值无关。这是从异步函数返回数据的经典问题。你不能同步返回它。您必须通过回调或承诺返回它,这就是整个问题的意义所在。您可以在此处阅读有关一般主题的信息:stackoverflow.com/questions/14220321/…
    • @jfriend00 你能告诉我上面编辑的代码运行良好还是有问题。
    • 我不是写这个问题的人。你将不得不问他们。我写了一个不同的答案,它使用承诺而不是普通的回调。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 2012-01-12
    • 2016-03-21
    • 2016-07-07
    • 2015-07-15
    • 2018-09-24
    • 1970-01-01
    相关资源
    最近更新 更多