0

I have a function that connect to a web service in SOAP. Unfortunately the web service only support a very limited connections. I have an array of items to search in the web service, if i do a for or a foreach loop, the 70% of cases complete with no error, but in the 30% the web service response a error. This occurs when the max connections is overflow. This happens because the loop is no waiting the response of the webservice and the loop cotinues creating a lot of connections.

Here's my code:

var promiseArray = [];

for (var i = 0; i < result.length; i++) {

  let m = result[i].id
  let xml = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">' +
    '<soapenv:Header/>' +
    '<soapenv:Body>' +
    '<tem:EjecutarConsultaXML>' +
    '<!--Optional:-->' +
    '<tem:pvstrxmlParametros>' +
    '<![CDATA[' +
    '<Consulta><NombreConexion>USERNAME</NombreConexion>' +
    '<IdConsulta>QUERY</IdConsulta>' +
    '<Parametros>' +
    '<doc>' + m + '</doc>' +
    '</Parametros>' +
    '</Consulta>' +
    ']]>' +
    '</tem:pvstrxmlParametros>' +
    '</tem:EjecutarConsultaXML>' +
    '</soapenv:Body>' +
    '</soapenv:Envelope>';

  const options = {
    explicitArray: true
  };


  promiseArray.push(new Promise(async(resolve, reject) => {
    await axios.post(url, xml, {
        headers: {
          'Content-Type': 'text/xml;charset=UTF-8'
        }
      })
      .then((data) => {
        xml2js.parseString(data.data, options, (err, result) => {
          var temp = (result['soap:Envelope']['soap:Body'][0]['EjecutarConsultaXMLResponse'][0]['EjecutarConsultaXMLResult'][0]['diffgr:diffgram'][0]['NewDataSet'][0]['Resultado'])
          resolve({
            doc: m,
            state: temp[0].f430_ind_estado[0]
          })
        });
      })
      .catch((err) => {
        console.log(err)
      });
  }))

}


res.send(await Promise.all(promiseArray))
Randy Casburn
  • 13,840
  • 1
  • 16
  • 31

2 Answers2

1

There are several issues with your code within the call to promiseArray.push().

  1. There is no need to create a new Promise() since axios already provides one
  2. There is no need for async/await in that call for the same reason.
  3. Mixing Promises and functions that use callbacks usually doesn't turn out too well
  4. You have no error checking in your code if the XML parser fails
  5. The option object is not required as explicitArray: true is the default

Changes:

  1. Removed all the extra/uneeded Promise code
  2. Replaced xml2js.parseString with xml2js.parseStringPromise
  3. Changed resolve to return
  4. Since you're simply console.log() the error, removed unecessary boilerplate

Everything else is OK as written. Please let me know if I've missed something.

promiseArray.push(
  axios.post(url, xml, {
    headers: {
      'Content-Type': 'text/xml;charset=UTF-8'
    }
  })
  .then(data=>data.data)
  .then(xml2js.parseStringPromise)
  .then(result => {
    var temp = result['soap:Envelope']['soap:Body'][0]['EjecutarConsultaXMLResponse'][0]['EjecutarConsultaXMLResult'][0]['diffgr:diffgram'][0]['NewDataSet'][0]['Resultado'];
    return {
      doc: m,
      state: temp[0].f430_ind_estado[0]
    };
  });
  .catch(console.log)
);
Randy Casburn
  • 13,840
  • 1
  • 16
  • 31
  • 1
    It works, but i need to put an "await" in the axios.post, because i receveid this `Promise { },` , but with the await works great. – Mateo Buitrago Feb 18 '21 at 12:22
0

Just do it one by one, using async/await to do that, this means you have to use parseStringPromise instead.

var response = [];

for (var i = 0; i < result.length; i++) {
  let m = result[i].id
  let xml = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">' +
    '<soapenv:Header/>' +
    '<soapenv:Body>' +
    '<tem:EjecutarConsultaXML>' +
    '<!--Optional:-->' +
    '<tem:pvstrxmlParametros>' +
    '<![CDATA[' +
    '<Consulta><NombreConexion>USERNAME</NombreConexion>' +
    '<IdConsulta>QUERY</IdConsulta>' +
    '<Parametros>' +
    '<doc>' + m + '</doc>' +
    '</Parametros>' +
    '</Consulta>' +
    ']]>' +
    '</tem:pvstrxmlParametros>' +
    '</tem:EjecutarConsultaXML>' +
    '</soapenv:Body>' +
    '</soapenv:Envelope>';

  const options = {
    explicitArray: true
  };

  try {
    var { data } = await axios.post(url, xml, { // extract data from data.data
      headers: {
        'Content-Type': 'text/xml;charset=UTF-8'
      }
    })

    var xmlObject = await xml2js.parseStringPromise(data)
    var temp = (xmlObject['soap:Envelope']['soap:Body'][0]['EjecutarConsultaXMLResponse'][0]['EjecutarConsultaXMLResult'][0]['diffgr:diffgram'][0]['NewDataSet'][0]['Resultado'])

    response.push({
      doc: m,
      state: temp[0].f430_ind_estado[0]
    }) // push item to result array
  } catch (error) {
    console.log(error);
  }

}

res.send(result) // send the result to client
hoangdv
  • 15,138
  • 4
  • 27
  • 48