SOAP API调用Javascript期间的异步/等待问题
希望有人能给我指出正确的方向。在继续之前,我阅读了等待函数完成的内容,我决定使用wait/async,但现在我被卡住了 我试图让Async/Await进程工作,尝试在不同的位置注入Await,并将函数调整为Async,但我无法让PSA_Resultbody返回到原始请求。任何指点都将不胜感激 谢谢, 行政长官 呼吁:SOAP API调用Javascript期间的异步/等待问题,javascript,node.js,api,Javascript,Node.js,Api,希望有人能给我指出正确的方向。在继续之前,我阅读了等待函数完成的内容,我决定使用wait/async,但现在我被卡住了 我试图让Async/Await进程工作,尝试在不同的位置注入Await,并将函数调整为Async,但我无法让PSA_Resultbody返回到原始请求。任何指点都将不胜感激 谢谢, 行政长官 呼吁: async function ProcessPSAAPI(xmlpackage, PSA_Action) { //psa action is part of the option
async function ProcessPSAAPI(xmlpackage, PSA_Action) { //psa action is part of the options
var options = {...};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log('0 - Start '+body.toString());
if(res.statusCode != 200) {
PSA_Resultcode = "Error: " +res.statusCode +" - "+ res.statusMessage;
} else {
PSA_Resultcode = "Success: " +res.statusCode +" - "+ res.statusMessage;
PSA_Resultbody = ParseResults(body.toString()); //parse the results for later use --SCRIPT NEEDS TO WAIT FOR RESULTBODY TO COMPLETE
console.log("1 -PSA_Resultbody as part of RES = "+PSA_Resultbody);
}
});
res.on("error", function (error) {
console.error(error);
PSA_Resultcode = res.statusCode +" - "+ res.statusMessage;
});
});
console.log('2 -RESULT BODY BEFORE SENDING BACK TO INITIATING FUNCTION: '+PSA_Resultbody);
req.write(xmlpackage);
req.end();
return PSA_Resultbody;
基于以上,我的控制台日志顺序是:3,2,0,1,而不是0,1,2,3
0和1将具有正确的数据,因此API调用确实有效,但2将是“未定义”的,并且应该具有与1中相同的数据。无法等待事件发射器,因此在这种情况下使用async是没有用的。您也不能从事件内部“返回” 这里的解决方案是返回一个新的自定义承诺,并在发射器的“end”事件中使用resolve() 它看起来像这样:
const myPromise = new Promise(function(resolve, reject) {
/* Your logic goes in here. It can be anything.
* But the important part to remember is that when you have success, resolve it.
* When you have a failure, reject it.
*/
someCallBackPattern(function(error, data) {
if(error) {
reject(error);
} else {
resolve(data);
}
});
});
// To get the data out you use 'then', and 'catch'. then has two arguments.
myPromise.then(function(data) {
// The first argument is the result from resolve.
}, function(err) {
// The second argument is the result from reject.
}).catch((err) => {
// you can also get to the error from the catch callback
});
函数处理PSAAPI(xmlpackage,PSA_操作){
返回新承诺((解决、拒绝)=>{
//其他代码
res.on(“结束”,函数(块){
//其他代码
解决(PSA_结果体);
});
res.on(“错误”,函数(错误){
//其他代码
拒绝(错误);
});
});
}
下面是一篇关于创建自己的承诺的文章,我写这篇文章是为了简化对这个主题的理解(官方文档有点枯燥和复杂,imho)。我没有更改您的代码。我只是把适当的承诺结构放进去让你开始。这应该是承诺的一个教训。async await是一种速记承诺结构。承诺是你等待代码的一种方式。它可以被看作是一个回调数组,当承诺得到解决时将执行回调 一个简单的承诺是这样的:
const myPromise = new Promise(function(resolve, reject) {
/* Your logic goes in here. It can be anything.
* But the important part to remember is that when you have success, resolve it.
* When you have a failure, reject it.
*/
someCallBackPattern(function(error, data) {
if(error) {
reject(error);
} else {
resolve(data);
}
});
});
// To get the data out you use 'then', and 'catch'. then has two arguments.
myPromise.then(function(data) {
// The first argument is the result from resolve.
}, function(err) {
// The second argument is the result from reject.
}).catch((err) => {
// you can also get to the error from the catch callback
});
这有点混乱和复杂。因此,存在异步等待
async function() {
try {
const result = await myFunctionThatReturnsAPromise();
// result is the resolved data
} catch (err) {
// err is the rejected Error
}
}
function myFunctionThatReturnsAPromise() {
return new Promise((resolve, reject) => {
// your code
})
}
这就是它的工作原理
async function someFunction () { // You can not wait on results unless you are in an await function
PSA_Resultbody = await ProcessPSAAPI(xmlpackage, PSA_Action); // await on your results.
console.log("3 - Returned data:" + PSA_Resultbody);
}
function ProcessPSAAPI(xmlpackage, PSA_Action) { // This does not need to be async. Unless you are awaiting in it.
return new Promise((resolve, reject) => { // async await is a shorthand promise structure. Although you do not need to use promises. It really helps to get the structure correct.
var options = {...};
var req = https.request(options, function (res) {
var chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function (chunk) {
var body = Buffer.concat(chunks);
console.log('0 - Start '+body.toString());
if(res.statusCode != 200) {
PSA_Resultcode = "Error: " +res.statusCode +" - "+ res.statusMessage;
reject(new Error(PSA_Resultcode)); // Reject you errors
} else {
PSA_Resultcode = "Success: " +res.statusCode +" - "+ res.statusMessage;
PSA_Resultbody = ParseResults(body.toString()); //parse the results for later use --SCRIPT NEEDS TO WAIT FOR RESULTBODY TO COMPLETE
console.log("1 -PSA_Resultbody as part of RES = "+PSA_Resultbody);
resolve(PSA_Resultbody); // Resolve your result
}
});
res.on("error", function (error) {
console.error(error);
PSA_Resultcode = res.statusCode +" - "+ res.statusMessage;
reject(new Error(PSA_Resultcode)); // Reject you errors
});
});
console.log('2 -RESULT BODY BEFORE SENDING BACK TO INITIATING FUNCTION: '+PSA_Resultbody);
req.write(xmlpackage);
req.end();
})
}
应该注意的是,async await本质上是在承诺中包装代码。如果没有等待,简单地向函数添加async将一事无成。“我会看看我是否能给你一些有用的东西。”@PatrickRoberts我对我的答案进行了编辑,使之更清楚一些,我不确定是否有必要。我的编辑是否足够?是的,看起来不错,我只是做了一个小的语法调整。我想我是想通过尝试将等待作为api调用的一部分来简化创建承诺的过程。谢谢你的解释。谢谢你把我的代码转换成上面的格式。。。这确实有帮助。