2016-09-27 83 views
4

我想从feathers.js钩子中的集合中获取信息。 如何让挂钩等待,直到mongodb调用完成?在它发出的钩无需等待呼叫到结束的那一刻,我想它的回报和promieses,但是毫无效果MongoDB在feathers.js中调用钩子

// Connection URL 
 
const url = 'mongodb://localhost:27017/db'; 
 

 
//Use connect method to connect to the server 
 

 
module.exports = function(hook) { 
 
    MongoClient.connect(url, function(err, db) { 
 
    const userCollection = db.collection('question'); 
 

 
    userCollection.count().then(function(N) { 
 

 
    const R = Math.floor(Math.random() * N) 
 

 
    const randomElement = userCollection.find().limit(1).skip(R).toArray(function(err, docs) { 
 
    console.log("Found the following records"); 
 
    console.log(docs) 
 
    //update hook with data from mongodb call 
 
    hook.data.questionid = docs._id; 
 
    }); 
 
    }) 
 
    }) 
 
};

回答

3

理想的做法是让hook asynchronous,并返回一个Promise与挂钩对象解决:

// Connection URL 
const url = 'mongodb://localhost:27017/db'; 
const connection = new Promise((resolve, reject) => { 
    MongoClient.connect(url, function(err, db) { 
    if(err) { 
     return reject(err); 
    } 

    resolve(db); 
    }); 
}); 

module.exports = function(hook) { 
    return connection.then(db => { 
     const userCollection = db.collection('question'); 
     return userCollection.count().then(function(N) { 
     const R = Math.floor(Math.random() * N); 

     return new Promise((resolve, reject) => { 
      userCollection.find().limit(1) 
      .skip(R).toArray(function(err, docs) { 
       if(err) { 
       return reject(err); 
       } 

       hook.data.questionid = docs._id; 

       resolve(hook); 
      }); 
     }); 
     }); 
    }); 
    }); 
}; 
+1

非常感谢,我认为这个解决方案比较好,但是我需要移动'return new Promise((resolve,reject)=> {'为'MongoClient.connect') – Hydish

+0

好点,我修改了代码示例 – Daff

0

You can use async.waterfall() of async module

const async=require('async'); 

async.waterfall([function(callback) { 
    userCollection.count().then(function(N) { 
    callback(null, N); 
    }); 
}, function(err, N) { 
    if (!err) { 
    const R = Math.floor(Math.random() * N) 
    const randomElement = userCollection.find().limit(1).skip(R).toArray(function(err, docs) { 
     console.log("Found the following records"); 
     console.log(docs) 
     //update hook with data from mongodb call 
     hook.data.questionid = docs._id; 
    }); 
    } 
}]) 
+1

感谢您的输入,我试了一下,发现了一些错误在我身边,但它仍然没有更新挂钩,它被写入数据库。 我目前的代码是: https://codeshare.io/tmLfO – Hydish

+0

你有什么错误?你可以在这里发布? – abdulbarik

+0

'hook'有'data'键吗? – abdulbarik

1

解决方式东西就是用

module.exports = function(hook, next) { 
    //insert your code 
    userCollection.count().then(function(N) { 
     const R = Math.floor(Math.random() * N) 
     const randomElement = userCollection.find().limit(1).skip(R).toArray(function(err, docs) { 
     console.log("Found the following records"); 
     hook.data.questionid = docs[0].email; 
     //after all async calls, call next 
     next(); 
     }); 

} 
0

DAFF的解决方案并没有为我工作。我得到了以下错误:

info: TypeError: fn.bind is not a function 

的解决方案是:它似乎正常钩可以用括号注册,但这个钩子有没有括号注册。 findEnemy

exports.before = { 
    all: [ 
    auth.verifyToken(), 
    auth.populateUser(), 
    auth.restrictToAuthenticated()], 
    find: [], 
    get: [], 
    create: [findEnemy], 
    update: [], 
    patch: [], 
    remove: [] 
}; 

findEnemy()不起作用。也许其他人遇到同样的问题。有人能解释为什么吗?

+0

因为前三个函数通过在实际运行中,它们返回什么?函数看起来像函数(钩子){} 现在看Daf f的钩子,他把中间人剪掉,没有函数返回函数(hook){},这就是那个函数的马上。如果您想使用“findEnemy()”,他的代码将如何显示:https://gist.github.com/medv/834cdb72ac1284bd19a47a3eb7cd582b – medv