2016-01-20 41 views
1

我有一個Node/Express路由功能,在另一個模塊中執行Redis呼叫。我想在一個節點模塊中執行一個複雜的Redis函數,併發送一個簡單的回調,告訴它路由模塊是成功的。 Redis調用會執行,但我無法執行任何同步函數,它們甚至從Redis調用中檢索一個簡單的真實值。這裏是我的Redis的功能:快速Node.JS - 接收Redis回調,執行承諾

doctorDB.js

var addDoctor = function addDoctor(id, doc){ 

    var fields = Object.keys(doc.fields); 

    return client.multi() 
     .sadd("Doctors", id) 
     .hmset(id, "lastName", doc.lastName, "firstName", doc.firstName) 
     .hmset(id, "email", doc.email, "university", doc.university, "work", doc.work) 
     .sadd(id + ":fields", fields) 
     .exec(function(err, replies){ 
      console.log("It's in this"); 
      if (doc.middleName){ 
       console.log("Now here"); 
       client.hset(id, "middleName", doc.middleName); 
       return true; 
      } else { 
       console.log("Or here"); 
       return true; 
      }      
     }); 
}; 

一切努力實現這一目標。現在我想要將回調發送到Express路由器以向客戶端發送響應。我希望它是一個同步函數的形式,我已經嘗試了許多使用Q和Async,但沒有任何工作。所以要麼A.我沒有完全掌握承諾函數,或者B.我沒有完全掌握將值返回給另一個模塊。任何幫助,將不勝感激。

以供參考,在這裏是在快遞路由器到底有多少失敗嘗試:我想通了這一點

routes.js

app.post('/addDoctorInfo', ensureLoggedIn('/login'), function(req, res, next){ 

    // function getThis(req){ 
    // var deferred = Q.defer(); 

    // doctorDB.addDoctor(req.body.id, req.body.doc).then(function(response){ 
    //  deferred.resolve(response); 
    // }, function(err){ 
    //  console.log(err); 
    //  return deferred.resolve(err); 
    // }); 
    // return deferred.promise; 
    // } 

    // var x = getThis(req); 
    // console.log(x); 

    doctorDB.addDoctor(req.body.id, req.body.doc).then(function(x){ 
     console.log(x); 
    }).catch(function(err){ 
     console.log(err); 
    }).finally(function(){ 
     console.log("We made it!"); 
    }); 


    // function sendMsg(info){ 
    // console.log(info); 
    // res.send({success: true}); 
    // } 
    // async.waterfall([ 
    // doctorDB.addDoctor(req.body.id, req.body.doc), 
    // sendMsg(info) 
    // ], function(err){ 
    // console.log(err) 
    // }); 

    // var DBCALL = doctorDB.addDoctor(req.body.id, req.body.doc); 

    // Q.fcall(DBCALL).then(function(x){ 
    // return console.log(x); 
    // }).catch(function(err){ 
    // console.log(err); 
    // }); 
}); 

回答

0

。我使用Q庫來執行所有的功能,而不是client.multi()。exec()。這允許清理執行所有redis post命令,然後允許我檢索信息。

在routes.js文件中,我只有一小段代碼。一切都在doctorDB.js文件中執行。

routes.js

app.post('/addDoctorInfo', ensureLoggedIn('/login'), function(req, res, next){ 
     return doctorDB.addDoctor(req.body.id, req.body.doc, req, res, next); 
}); 

doctorDB.js

var addDoctor = function addDoctor(id, doc, req, res, next){ 
    var fields = Object.keys(doc.fields); 

    function middleName(id, doc){ 
     if (doc.middleName){ return client.hset(id, "middleName", doc.middleName); } 
     else { return; } 
    } 

    return Q.all([Q.ninvoke(client, 'sadd', 'Doctors', id), 
        Q.ninvoke(client, 'hmset', id, "lastName", doc.lastName, "firstName", doc.firstName, "email", doc.email, "university", doc.university, "work", doc.work), 
        Q.ninvoke(client, 'sadd', id + ':fields', fields), 
        middleName(id, doc)]).then(function(x){ 
         return getInfo(id, req, res, next);; 
        }, function (err) { res.status(404); }); 
}; 

這得到到函數的getInfo(),其發送到客戶端側的響應傳遞:

var redisHGetAll = Q.nbind(client.hgetall, client); 

var getInfo = function getInfo(id, req, res, next){ 
    return redisHGetAll(id).then(function(x){ 
     return findByMatchingProperties(x); 
    }, function (err) { res.status(404); }).then(function(){ 
     return client.smembers(id + ':fields', function(err, reply){ 
      data['fields'] = reply; 
      res.setHeader('Content-Type', 'application/json'); 
      res.end(JSON.stringify(data)); 
     }); 
    }, function (err) { res.status(404); }) 
}; 

function findByMatchingProperties(x) { 
    for (var y in x){ 
     checkData(y, x[y]); 
    }  

    function checkData(y, z){ 
     for (var d in data){ 
      if (d === y){ 
       data[d] = z; 
      } 
     } 
    } 
} 

var data = { 
    lastName: null, 
    firstName: null, 
    middleName: null, 
    email: null, 
    university: null, 
    work: null, 
    fields: null 
};