我想在后端进行串行工作。我想选择geo_unit并做另一项工作并向客户端写回复。 我看了http://nodejs.org/docs/v0.4.7/api/events.html#events和Error: Can't set headers after they are sent to the client
当我慢慢发送请求时,一切正常每3秒1次。
但是当我快速发送请求时它不起作用。我得到以下错误。 我是否在全球范围内定义了什么?
Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (http.js:691:11) at ServerResponse.res.setHeader (E:\git\xxxxxx-nodejs\node_modules\express\node_modules\connect\lib\patch.js:63:22) at ServerResponse.res.set.res.header (E:\git\xxxxxx-nodejs\node_modules\express\lib\response.js:527:10) at ServerResponse.res.json (E:\git\xxxxxx-nodejs\node_modules\express\lib\response.js:194:36) at EventEmitter. (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:17:17) at EventEmitter.emit (events.js:117:20) at ScrapperAPI.externalLocationCallback (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:27:20) at Query._callback (E:\git\xxxxxx-nodejs\routes\api_scrapper.js:51:21) at Query.Sequence.end (E:\git\xxxxxx-nodejs\node_modules\mysql\lib\protocol\sequences\Sequence.js:78:24) at Query._handleFinalResultPacket (E:\git\xxxxxx-nodejs\node_modules\mysql\lib\protocol\sequences\Query.js:143:8)
我使用以下代码:
var express = require('express'), http = require('http'), path = require('path'); var app = module.exports = express(); var server = require('http').createServer(app); var io = require('socket.io').listen(server); var request = require('request'); var cheerio = require('cheerio'); var mysql = require('mysql'); var pool = mysql.createPool({ host : 'localhost', user : 'root', database :'evevgez_development', password : 'root', // socketPath : '/var/run/mysqld/mysqld.sock' }); var sahibinden = require('./routes/my_scrapper').newScrapperAPI(pool); app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.static(path.join(__dirname, 'public'))); app.use(app.router); app.use(express.errorHandler()); app.get('/node1', sahibinden.scrap); server.listen(app.get('port'), function () { console.log('Express server listening on port ' + app.get('port')); });
和myModule就是那样
var request = require('request'); var cheerio = require('cheerio'); var iconv = require('iconv-lite'); var EventEmitter = require('events').EventEmitter; var emitter= new EventEmitter(); function ScrapperAPI(pool) { this.scrap = function (req, res,next) { var query = req.query; console.log('req.params:'+req.query); console.log('IL_ID:'+query.il_id); emitter.emit('location',query); emitter.on('success',function(rows){ res.json(rows); }); }; emitter.on('location',function(query){ console.log('quey1:'+query); getExternalLocation(query ) }); var getExternalLocation = function (query ) { try { pool.getConnection(function (err, connection) { console.log('query:'+query); connection.query("select * from external_geo_units where geo_unit_id = ? ",query.il_id, function (err, rows) { console.log(err); if (err) callback(err); emitter.emit('success',rows); connection.release(); }); }); } catch (e) { console.log(e); } }; } module.exports.newScrapperAPI = function (pool) { return new ScrapperAPI(pool); }
答案 0 :(得分:6)
以这种方式使用EventEmitter并不是您正在做的事情的最佳解决方案,因为您只是在请求中使用它来进行数据库调用并返回一些行 - 只需回调即可轻松简单地完成。
但是,如果您想要保留全局EventEmitter,则必须将on
和emitter.on('success'
中的emitter.on('location'
切换为once
,以确保只调用一次根据要求。