使用promise和rediscallback

我试图用我在Redis服务器上的东西填充我的var todos ,我得到我必须使用承诺,但我可能不在正确的位置。

首先,我用.smembers()函数获取所有ids,并且为每个id获取具有正确id的对象并将其parsing为todos

 var todos=[]; res.locals.redis.smembers("todo:20", function(err, reply){ // ie SMEMBERS todo:20 returns 0 and 1 var promises=reply.map(function(elem){ res.locals.redis.get("todo:20:"+elem, function(err, reply1){ // ie GET todo:20:0 return new Promise(function(resolve, reject){ todos.push(JSON.parse(reply1)); resolve(); }); }); }); Promise.all(promises) .then(function(){ res.locals.redis.quit(); res.render('todolist.ejs', {todo: todos}); }) .catch(function(reason){ console.log(reason); }); }); 

问题在于你没有在正确的地方创造一个承诺。 它必须在map函数内部创build,而不是在redis.getcallback:

 res.locals.redis.smembers("todo:20", function(err, reply) { var promises = reply.map(function(elem) { return new Promise(function(resolve, reject) { res.locals.redis.get("todo:20:" + elem, function(err, reply1) { let todo = JSON.parse(reply1); resolve(todo); }); }); }); Promise .all(promises) .then(function(todos) { res.locals.redis.quit(); res.render('todolist.ejs', { todo: todos }); }) .catch(function(reason){ console.log(reason); }); }); 

但更好的解决scheme是创buildpromisify函数,并将所有callback式函数转换为promisified函数:

 let promisify = (fn, params) { return new Promise((resolve, reject) => { fn(params, (err, res) => { if (err) { reject(err); } else { resolve(res); } }); }); }; promisify(res.locals.redis.smembers, 'todo:20') .then(reply => { let promises = reply.map(elem => promisify(res.locals.redis.get, "todo:20:" + elem); return Promise.all(promises); }) .then(results => { let todos = results.map(item => JSON.parse(item)); res.locals.redis.quit(); res.render('todolist.ejs', { todo: todos }); }) .catch(err => console.log(err)); 

如果要将接受callback的asynchronous函数转换为返回承诺的函数,一般方法是将函数包装在承诺中,并将Promise构造函数提供的resolve作为callback传递:

 function getStuff(cb) { setTimeout(() => cb('stuff'), 1000); } function withPromise() { return new Promise(resolve => getStuff(resolve)); } withPromise().then(console.log);