2014-12-30 53 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',但它不起作用。 –