2014-12-30 54 views
2

我在node.js中有一个模块,它通过sequelize lib与postgres数据库连接。我的模块代码基本上是:在node.js中承诺蓝鸟的问题

// ofr-network/index.js 
var requireDir = require('require-dir'); 
var models = requireDir('./models'); 

var network = { 
    getReportsFromCity: function(cityId) { 
    models.index.reports.findAll({ 
     where: { id: cityId }, 
     attributes: ['id', 'latitude', 'longitude'] 
    }).then(function(reports) { 
     console.log('[NETWORK-OFR] Get reports from %s', cityId); 
     return reports; 
    }).catch(function(err){ 
     console.log('Error getting reports from %s', cityId); 
     console.log(err); 
    }); 
    } 
} 

module.exports = network; 

那么,这段代码工作正常。现在我正在尝试在我的快速应用程序中使用此模块,导入并调用此方法,但此代码不返回任何内容。我查过了,看到我必须使用承诺,一旦上面的代码是异步的。 我的API方法的代码如下:

var express = require('express'); 
var app = express(); 
var router = express.Router(); 
var network = require('ofr-network'); 
var Promise = require('bluebird'); 

router.get('/', function(req, res) { 
    var getReports = Promise.promisify(network.getReportsFromCity, network); 
    getReports(538).then(function(reports) { 
    console.log('DONE'); 
    // this print isn't running 
    }).catch(function(err){ 
    console.log(err); 
    }); 
    res.render('index.html', { title: 'Title page' }); 
}); 

module.exports = router; 

有人能帮助我吗?

+0

你为什么promisify'getReports'? promisify是为了使回调函数返回承诺,'getReports'已经返回一个承诺 – Esailija

回答

3

承诺代表价值+时间。信守诺言,他们就会开始为待定,并且可以稳定到:

  • 满足这意味着计算成功完成。
  • 拒绝这意味着计算失败。

返回承诺的函数(如集合函数)让您可以在前一个承诺实现时运行的承诺then上挂钩。你可以链接承诺(就像你已经完成),但不要忘记他们到外面。承诺利用钩子的返回值。

Promise.promsify需要一个以(err, data)格式进行回调的函数 - 在您的代码中没有必要使用promise。这对于promisification很有用,但这不是这种情况。

相反 - 你只需要返回的承诺,所以你可以使用它:

var network = { 
    getReportsFromCity: function(cityId) { 
    return models.index.reports.findAll({ // NOTE THE RETURN 
     where: { id: cityId }, 
     attributes: ['id', 'latitude', 'longitude'] 
    }).then(function(reports) { 
     console.log('[NETWORK-OFR] Get reports from %s', cityId); 
     return reports; 
    }).catch(function(err){ 
     console.log('Error getting reports from %s', cityId); 
     console.log(err); 
    }); 
    } 
} 

这将让你做的事:

network.getReportsFromCity(538).then(function(data){ 
    console.log("Data", data); 
}); 

不要忘了,承诺不转换异步代码到同步代码,只是一个有用的工具 - 不是魔术:)一切以外承诺链仍然可以发生在链本身运行之前。您的res.render放错了位置 - 您需要将其放入最终的then并附上相关数据。

+0

太贵了。它工作正常!感谢您对承诺的解释。 :) –

+0

@ marciovicente.filho我很高兴能够帮助 - 随时提出更多诺言问题 - 我们正在努力在此创建知识库:) –

0

你可以试着把res.render('index.html', { title: 'Title page' });后面的行console.log('DONE');? 看起来响应在您得到getReports结果之前被调用。

+0

嗨@ChinKang,我已经尝试把rende放入'then',但它不起作用。 –