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))

2 Answers 2

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)
);
Sign up to request clarification or add additional context in comments.

1 Comment

It works, but i need to put an "await" in the axios.post, because i receveid this Promise { <pending> }, , but with the await works great.
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.