具有快速的节点发射器

时间:2014-04-26 14:05:03

标签: node.js express

我想在后端进行串行工作。我想选择geo_unit并做另一项工作并向客户端写回复。 我看了http://nodejs.org/docs/v0.4.7/api/events.html#eventsError: 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);
}

1 个答案:

答案 0 :(得分:6)

以这种方式使用EventEmitter并不是您正在做的事情的最佳解决方案,因为您只是在请求中使用它来进行数据库调用并返回一些行 - 只需回调即可轻松简单地完成。

但是,如果您想要保留全局EventEmitter,则必须将onemitter.on('success'中的emitter.on('location'切换为once,以确保只调用一次根据要求。