在node.js中遇到promises bluebird的麻烦

时间:2014-12-30 17:52:32

标签: javascript node.js promise bluebird

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

// 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;

嗯,这段代码运行正常。现在我尝试在我的快速应用程序中使用此模块,导入并调用此方法,但此代码不返回任何内容。我已经搜索过,看到我必须使用promises,一旦上面的代码是异步的。 我的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;

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

承诺代表价值+时间。承诺有状态,他们开始等待,并可以解决:

  • 履行意味着计算成功完成。
  • 拒绝表示计算失败。

返回promises的函数(如sequelize函数)允许您挂钩then的承诺,这些承诺在前一个承诺完成时运行。你可以链接承诺(就像你已经完成的那样),但不要忘记return它们到外面。 Promise利用钩子的返回值。

Promise.promsify接受一个以(err, data)格式进行回调的函数 - 在您的代码中没有必要使用promises。它对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);
});

不要忘记,promises不会将异步代码转换为同步代码,只是一个有用的工具 - 而不是魔术:)在链本身运行之前,所有外部的承诺链仍然可以发生。您的res.render放错了地方 - 您需要将其与相关数据放在最终then中。

答案 1 :(得分:0)

你可以尝试在res.render('index.html', { title: 'Title page' });行后面加上console.log('DONE');行吗? 似乎在你得到getReports结果之前调用了响应。