从Node.js

时间:2017-08-02 19:27:47

标签: javascript node.js rest asynchronous soap

我正在构建一个原型Web应用程序,它响应带有查询参数的GET请求,关闭并调用3个不同的Web服务,所有Web服务都有不同的有效负载 - 2个是ReST(一个返回二进制对象,一个图像,一个返回JSON),1是SOAP。

然后我需要将每个数据中的数据组合成一个HTML页面,该页面将返回原始GET请求。

我是异步编程的新手,我认为这就是我出错的地方。

对于SOAP我使用

var locationRequest = require('request');        
locationRequest(options1, function (error, response, output) {
...
}

对于ReST电话我使用两个类似的调用:

    var resourceJSON;
    var body2;
    var resourceHttp = require("https");          
    var resourceRequest = resourceHttp.request(resourceOptions, function (resourceRes) {
        var chunks2 = [];        
        resourceRes.on("data", function (chunk2) {
            body2 += chunk2;
        });
        resourceRes.on("end", function () {                
            resourceJSON = JSON.parse(body2);
        });
        resourceRes.on('error', function (error) {
            console.log('\n Error received: ' + error);
    });
    resourceRequest.end();
});

这些都发生在Express app.get,即

app.get('/myURL', function(req,res,next){
}

因此,我需要做的最后一件事就是组合这些响应并将一些HTML(包括数据)返回给调用者。
首先,我有一些(菜鸟,我确定)奇怪的变化范围。例如,如果我在app.get块的开头定义一个变量来保存来自ReST调用的JSON,那么在resourceRes.on(" data ...)函数中写入它,我得到一个如果我在app.et块的末尾引用它,则表明它未定义。

其次,由于这些调用都是异步启动的,如何在将数据汇总到我的HTML响应之前确定所有调用都已完成?

任何指导或帮助非常感谢!

修改

所以我已经把这个简单地剥离了,因为我遇到了一个问题,当我从浏览器提交请求以启动流程时,浏览器只需等待& #34;等待localhost"然后最终因套接字超时错误而失败。如果我通过Postman提交请求,我会按预期获得JSON响应。有线索吗?

现在代码如下:

app.get('/myurl', function(req,res,next){
var device = req.query.deviceId;
var resourceOptions = {
    "method": "GET",
    "hostname": "myhostname",
    "port": 443,
    "path": "/mypath/",
    "headers": {
        "authorization": "Basic HIDINGTHIS",
        "cache-control": "no-cache",
        "content-type": "application/json",      
    }
};

const resourceHttp = require("https");
const restRequest = () => {
    const promise = new Promise((resolve, reject) => {
        resourceHttp.request(resourceOptions, function (resourceRes) {
            var response = '';
            resourceRes.on("data", function (chunk2) {
                console.info('in on');  
                response += chunk2;
            });
            resourceRes.on("end", function () {
                console.info('in end');
                resolve(JSON.parse(response));
            });
            resourceRes.on('error', function (error) {
                console.info("in error");
                reject(error);
            });
            resourceRequest.end();
        });
    });
    return promise;
};

return restRequest()
.then(data => {
    // Send positive response from server
    console.info("succcess");
    res.end("DONE!");
})
.catch(err => {
    // Send negative response from server as there is an error
    console.info("error");
    res.end("ERROR!");
});     

});

2 个答案:

答案 0 :(得分:1)

您可以将它们包装在Promise中,然后使用Promise.all()在代码全部返回后运行代码:

app.get('/myURL', function(req, res, next){
    var soapPromise = new Promise(function(resolve, reject) {
        locationRequest(options1, function(error, response, output) {
            if (error) reject(error);
            else resolve(response);
        })
    });
    var restPromise = new Promise(function(resolve, reject) {
        resourceHttp.request(resourceOptions, function(resourceRes) {
            var body = '';
            resourceRes.on("data", function (chunk) {
                body += chunk;
            });
            resourceRes.on("end", function () {
                resolve(JSON.parse(body));
            });
            resourceRes.on('error', function (error) {
                console.log('\n Error received: ' + error);
                reject(error);
            });
            resourceRequest.end();
        });
    });
    Promise.all([soapPromise, restPromise])
        .then(function([soapResult, restResult]) {
            //respond to client
        })
        .catch(function(error) {
            //catch an error generated from either request
        })
})

答案 1 :(得分:0)

您可以使用承诺,.then().catch(),如下所示:

  const locationRequest = require('request');
  const resourceHttp = require("https");

  const soapRequest = () => {
    const promise = new Promise((resolve, reject) => {
      locationRequest(options1, function (error, response, output) {
        if(error)
          reject(error);
        else
          resolve(response);
      });
    });
    return promise;
  };

  const restRequest = () => {
    const promise = new Promise((resolve, reject) => {
      resourceHttp.request(resourceOptions, function (resourceRes) {
        var response = '';
        resourceRes.on("data", function (chunk2) {
          response += chunk2;
        });
        resourceRes.on("end", function () {
          resolve(JSON.parse(response));
        });
        resourceRes.on('error', function (error) {
          reject(error);
        });
        resourceRequest.end();
      });
    });
    return promise;
  };

  return soapRequest()
    .then(restRequest)
    .then(data => {
      // Send positive response from server

    })
    .catch(err => {
      // Send negative response from server as there is an error

    });