2017-09-28 15 views
1

私はを私のRedisサーバーに入れようとしています。私は約束を使わなければなりませんが、私はおそらく正しい場所にいません。redisコールバックで約束を使用

まず、.smembers()のすべてのIDを取得し、IDごとに正しいIDのオブジェクトを取得し、それをtodosに解析しています。

var todos=[]; 
res.locals.redis.smembers("todo:20", function(err, reply){ // i.e. SMEMBERS todo:20 returns 0 and 1 
    var promises=reply.map(function(elem){ 

     res.locals.redis.get("todo:20:"+elem, function(err, reply1){ // i.e. 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); 
    }); 
}); 

答えて

1

ようになります。それはmap関数の内部ではなく、redis.getコールバックの内部で作成する必要があります。

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); 
    }); 
}); 

しかし、もっと良い解決策はpromisify関数を作成し、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)); 
+0

このpromisify関数はローディング速度を変更しますか?私はそれが良く見えるが、私はまだ私が前の答えよりもよかった理由は混乱している –

+0

答えは**なし**、_promisify_機能はパフォーマンスに影響しません。例で見てきたように、単純なロジックを持つオブジェクトを返します。エラーがある場合は 'reject'約束を返し、それ以外の場合は非同期呼び出しの結果を' resolve'します。 – alexmac

1

あなたが約束を返す関数へのコールバックを受け入れる非同期機能を変換したい場合は、一般的なアプローチは約束で関数をラップし、コールバックとしてPromiseコンストラクタによって提供さresolveを渡すことです:

function getStuff(cb) { 
 
    setTimeout(() => cb('stuff'), 1000); 
 
} 
 

 
function withPromise() { 
 
    return new Promise(resolve => getStuff(resolve)); 
 
} 
 

 
withPromise().then(console.log);

これは、代わりにあなたのRedisのコールバック内の約束の作成を置くこと、あなたがそれアウトを移動しなければならない、ということを意味それのIDEは:

res.locals.redis.get("todo:20:"+elem, function(err, reply1){ // i.e. GET todo:20:0 
    return new Promise(...); // <-- move this outside of the callback 
}); 

それは問題は、あなたが正しい場所にない約束を作成することである

var promises = reply.map(function(elem){ 
    return new Promise(function(resolve, reject){ 
    res.locals.redis.get("todo:20:"+elem, function(err, reply1) { 
     todos.push(JSON.parse(reply1)); 
     resolve(); 
    }); 
    }); 
}); 
関連する問題