我不能让发射器在回叫之前发出从pg模块返回的信号。这是我的情况。
questionHandler_upqid.js:
var express = require('express');
var router = express.Router();
var pg = require('pg');
var connectionString = process.env.DATABASE_URL || 'postgres://admin:admin@localhost:5432/mydb';
var question_id;
var resource_id = [];
//var err_ = []; //Move to local function
var mcres = [];
exports.addResourceFile = function(req, res, err, client, done, callback){
var cb_is_func = (typeof(callback)==='function');
console.log('addResourceFile function called');
var err_ = [];
var resourcefiles = req.body.resourcefiles;
var idx = 0;
//Use local function because of err + client + done scope.
exports.addResourceFile_inside = function (element, index, array){
console.log('addResourceFile_inside function called, index : ' + index);
var func_ = 'SELECT Dugong.resourcefile_Add($1,$2,$3)';
//rfdata = resource file data.
var rfdata = [element.fileurl,
element.name,
element.type];
console.log(rfdata);
var addResourceFile_ = client.query(func_, rfdata);
//Add underscore (_) to prevent confusion.
addResourceFile_.on('error', function(err){
console.log('error signal from addResourceFile');
var tempdata = {success : false,
id : -1,
reason : {errmsg : err.detail,
errid : 'addResourceFile' + index }}; //plus index to spot record
err_.push(tempdata);
});
addResourceFile_.on('row', function(row){
console.log('row signal from addResourceFile_');
resource_id.push(row.resourcefile_add);
});
console.log('hello world');
callback(err_, resource_id);
return ;
};
/*
//Want sequential run of these.
//But it does not.
resourcefiles.forEach(exports.addResourceFile_inside);
callback(err_, resource_id);
return ;
*/
//Emitter emits lastest. callback executed first.
exports.action = function(){
resourcefiles.forEach(exports.addResourceFile_inside);
};
exports.summary = function(){
callback(err_, resource_id);
};
exports.summary(
exports.action()
);
};
我的单元测试: questionHandler_upqid.js
var httpMocks = require('node-mocks-http');
var test = require('unit.js');
var real_questionHandler = require('../routes/questionHandler_upqid.js');
var proxyquire = require('proxyquire'),
pgStub = { };
var events = require('events');
describe('questionHandler_upqid : ', function () {
var request;
beforeEach(function (){
request = httpMocks.createRequest({
method: 'PUT',
url: '/questions',
params: {id : 1 },
body : { questiontype : 'Multiple Choice',
problemtext : 'Find x when x is 4 + 2',
excerpttext : 'Somewhere I belong',
solutiontext : '6',
authorid: 'Sarit1',
subjectid: '2',
lastmod: '2099-0101 00:00:02',
resourcefiles : [{"name":"penguin","type":"jpeg","fileurl":"/1.jpeg"},
{"name":"penguin","type":"jpeg","fileurl":"/2.jpeg"},
{"name":"penguin","type":"jpeg","fileurl":"/3.jpeg"},
{"name":"penguin","type":"jpeg","fileurl":"/4.jpeg"},
{"name":"penguin","type":"jpeg","fileurl":"/5.jpeg"}],
mcresponses : [{"text":"BX","image":"A1","iscorrect":false},
{"text":"BW","image":"A2","iscorrect":false},
{"text":"ACRA","image":"A3","iscorrect":true},
{"text":"GxM","image":"A4","iscorrect":false}]
//Do not change lenght of mcresponse.
//mcres_length is used in 'should add MCResponse with error'
}
});
pgStub.end = function(){};
});
it('should add ressource file with error', function(done){
//emitter emit 'error'
var client = {};
client.query = function(querystr, data){
var emitter = new events.EventEmitter();
setTimeout(function(){
console.log('emit diode add resource file with error');
error = {detail : 'Resrc file can be changed!'};
emitter.emit('error', error);
},0);
console.log('add emitters');
return emitter;
};
var response = httpMocks.createResponse();
var questionHandler_upqid = proxyquire('../routes/questionHandler_upqid.js', { 'pg' : pgStub} );
questionHandler_upqid.addResourceFile(request, response, null, client, null, function(err, resrc_id){
console.log(err);
console.log(resrc_id);
done();
});
});
});
此代码在调用回调后仍会发出。
var p1 = new Promise(function(){
resourcefiles.forEach(exports.addResourceFile_inside);
});
p1.then(callback(err_, resource_id));
我有2个空白的err_和resource_id数组。然后拿出来自发射器的信号。实际上我希望先执行发射器然后再回调。回调应该返回2个数组。它们是err_和resource_id。
答案 0 :(得分:0)
您需要将回调绑定到其中一个pg
的事件,以便在调用之前知道查询已完成。
与'row'
和'error'
事件一起,其Query
个对象也会发出'end'
event when all rows have been received successfully:
addResourceFile_.on('row', function(row){
console.log('row signal from addResourceFile_');
resource_id.push(row.resourcefile_add);
});
addResourceFile_.on('end', function () {
callback(null, resource_id);
});
但是,如果存在错误,则不会发出'end'
事件(因此您可以安全地假设为null
),因此您需要从callback
调用'error'
{1}}事件也包括成功和失败:
addResourceFile_.on('error', function (err) {
console.log('error signal from addResourceFile');
var tempdata = {
success : false,
id : -1,
reason : {
errmsg : err.detail,
errid : 'addResourceFile' + index // plus index to spot record
}
};
callback(tempdata, null);
});
答案 1 :(得分:0)
我不知道这是一个好的编码风格,但仅仅是暂时的。我顺便去了。
addResourceFile_.on('error', function(err){
console.log('error signal from addResourceFile');
var tempdata = {success : false,
id : -1,
reason : {errmsg : err.detail,
errid : 'addResourceFile' + index }}; //plus index to spot record
err_.push(tempdata);
console.log(idx);
if(idx === array.length - 1){
callback(err_, resource_id);
}
idx = idx + 1;
});
addResourceFile_.on('row', function(row){
console.log('row signal from addResourceFile_');
resource_id.push(row.resourcefile_add);
if(idx === array.length - 1){
callback(err_, resource_id);
}
idx = idx + 1;
});