如何使用node / express处理需要两个异步方法的请求

时间:2013-12-10 03:36:52

标签: javascript node.js asynchronous promise

我正在学习节点。我有一个Web应用程序通过bitcoin包与bitcoind连接,PostgreSQL通过knex连接。我需要从每个模块中获取一些数据,然后将其全部传递给我的视图以进行渲染。到目前为止,我的代码看起来像这样:

exports.index = function(req, res){
  var testnet='';
  bitcoin.getInfo(function(e, info){
    if(e){ return console.log(e);}
    if(info.testnet){
      testnet='bitcoin RPC is testnet';
    }else{
      testnet='nope.. you must be crazy';
    }
    var c=knex('config').select().then(function(k){
      res.render('index', { title: k[0].site_name, testnet: testnet });
    });
  });
};

虽然这是结构化的方式,它将首先等待比特币回复,然后它会向PostgreSQL发出请求,然后等待一段时间让它回复。这两个等待时间显然可以同时发生。但是,我不知道如何使用Javascript中的promises / callbacks来做到这一点。如何管理这种情况是异步发生的,而不是连续发生的?

3 个答案:

答案 0 :(得分:3)

您正在寻找async模块,它可以让您启动这两项任务,然后继续。

一个未经考验的例子给你的想法:

exports.index = function(req, res){
    var testnet='', k={};

    async.parallel([
      function(){ 
        bitcoin.getInfo(function(e, info){
          //your getInfo callback logic
           },
      function(){
        knex('config').select().then(function(result) {       
         //your knex callback
         k = result;
      } ],
      //Here's the final callback when both are complete
      function() {
         res.render('index', { title: k[0].site_name, testnet: testnet });
      });
}

答案 1 :(得分:2)

您可以使用caolan/async #parallel()方法之类的库,也可以查看其源代码并学习自己的角色

答案 2 :(得分:1)

你需要宣传回调方法,而不是混合回调和承诺。

var Promise = require("bluebird");
var bitcoin = require("bitcoin");
//Now the bitcoin client has promise methods with *Async postfix
Promise.promisifyAll(bitcoin.Client.prototype);

var client = new bitcoin.Client({...});

然后是实际代码:

exports.index = function(req, res) {
    var info = client.getInfoAsync();
    var config = knex('config').select();

    Promise.all([info, config]).spread(function(info, config) {
        res.render('index', {
            title: config[0].site_name,
            testnet: info.testnet ? 'bitcoin RPC is testnet' : 'nope.. you must be crazy'
        });
    }).catch(function(e){
        //This will catch **both** info and config errors, which your code didn't
        //do
        console.log(e);
    });
};

使用了承诺模块bluebird