我有一个问题,我正在使用node-soap和pg-promise。我有一个问题,当我向soap服务请求响应被延迟时,换句话说,我必须在响应返回之前发送请求两次(使用soap ui):
我想知道我是不是将数据库调用的响应正确传递给节点soap回调:
以下是node-soap网站的示例代码:
var myService = {
MyService: {
MyPort: {
MyFunction: function(args) {
return {
name: args.name
};
},
// This is how to define an asynchronous function.
MyAsyncFunction: function(args, callback) {
// do some work
callback({
name: args.name
});
},
// This is how to receive incoming headers
HeadersAwareFunction: function(args, cb, headers) {
return {
name: headers.Token
};
},
// You can also inspect the original `req`
reallyDeatailedFunction: function(args, cb, headers, req) {
console.log('SOAP `reallyDeatailedFunction` request from + req.connection.remoteAddress);
return {
name: headers.Token
};
}
}
}
};
var xml = require('fs').readFileSync('myservice.wsdl', 'utf8'),
server = http.createServer(function(request,response) {
response.end("404: Not Found: " + request.url);
});
这是我的代码:
var http = require('http');
var soap = require('soap');
global.results = '';
var promise = require('bluebird'); //
var options = {
promiseLib: promise // switch to bluebird lib
};
// Database connection details;
var cn = {
host: '',
port: 5432,
database: '',
user: '',
password: ''
};
var pgp = require('pg-promise')(options);
var db = pgp(cn);
var cancelService = {
cancelService: {
Cancel_PortType: {
getAgreement: function(args,callback,headers) {
var values = {
vin: args.vin
};
db.any("select contract_num as contract, " +
"CASE WHEN sg_con_status='A' THEN 'Active ' " +
"WHEN sg_con_status='X' THEN 'Expired' " +
"WHEN sg_con_status='C' THEN 'Cancelled' " +
"END AS agreementStatus, " +
"tfs_product_type as productType, " +
"vin, cust_first_name as customerFirstName, cust_last_name as customerLastName," +
"TO_CHAR(original_busdate,'YYYY-MM-DD') as purchaseDate, TO_CHAR(expire_date,'YYYY-MM-DD') as expirationDate " +
"from tfs_contract_summary, sg_con_m1 where sg_con_m1.sg_con_contract = tfs_contract_summary.contract_num " +
" AND vin = ${vin}",values)
.then(function(data) {
//set value of DB return to global
global.results = data;
console.log("DATAAAAAAA:", data);
})
.catch(function(error) {
console.log("ERROR:", error); // print the error;
})
.finally(function() {
pgp.end(); //closing the connection pool.
});
// }
callback({
contracts: global.results
});
}
}
}
}
var xml = require('fs').readFileSync('CancelService.wsdl', 'utf8'),
server = http.createServer(function(request, response) {
response.end("404: Not Found: " + request.url)
});
server.listen(8000);
soap.listen(server, '/wsdl', cancelService, xml);
我的所有console.log()都显示每次在SOAPUI中发出请求时返回的数据,但响应在我发送请求的2次之后才会返回:
例如
按一下按钮: vin = 12312364812736498
我希望John doe信息能够返回 - console.log(John doe' s信息) SOAP RESPONSE =空
按两次按钮 console.log(John doe' s信息) SOAP RESPONSE = John doe的信息
如果我使用提供的soap客户端示例代码并发出请求:
console.log每次都有效:
我是否有范围问题,其中global.results值具有竞争条件?
我很确定我的代码可能有问题,因为我是Node JS等的新手......
我是否错误地传递了soap-server的回调?
callback({
contracts: global.results
});
非常感谢任何见解。
答案 0 :(得分:1)
我认为问题是你在设置global.results
之前调用了回调函数(即使它位于函数的底部)。
您的promise .then
和.catch
块中的所有代码都是异步运行的 - 这意味着它们被拖拽到事件循环中以便稍后运行;在当前代码完成之后。
以下是代码中发生的事情的顺序:
callback({contracts: global.results})
。此时,global.results
未定义。.then
和.catch
es。这里是您设置global.results
(当然为时已晚)global.results
已设置为上次查询的结果。解决方法是忘记使用global
并将回调放在承诺的.then
中:
db.any("my_awesome_sql")
.then(function(data) {
console.log("DATAAAAAAAA!!!", data);
callback({contracts: data});
})
.catch(function(error) {
// Handle error
})
.finally(function() {
// Cleanup
});