SOAP API调用Javascript期间的异步/等待问题

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

希望有人能给我指出正确的方向。在继续之前,我阅读了等待函数完成的内容,我决定使用wait/async,但现在我被卡住了

我试图让Async/Await进程工作,尝试在不同的位置注入Await,并将函数调整为Async,但我无法让PSA_Resultbody返回到原始请求。任何指点都将不胜感激

谢谢,

行政长官

呼吁:

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调用的一部分来简化创建承诺的过程。谢谢你的解释。谢谢你把我的代码转换成上面的格式。。。这确实有帮助。