Use closure as return of a function

Asked

Viewed 45 times

3

I need to use a variable of a closure as a return to the function to which this closure is nestled. How can I do this?

response must be the return of ajaxRequest():

function ajaxRequest(type, url) {
  const ajax = new XMLHttpRequest()

  ajax.onreadystatechange = () => {
    if(ajax.readyState === 4 && ajax.status === 200) {
      let response = parseToJson(ajax.responseText) // → JSON.parse(str)
      // ...
    }
  }

  ajax.open(type, url)
  ajax.send()

  // return response
}

ajaxRequest is called from two functions containing the request data: tradesRequest() and pricesRequest(). I need the return of these two functions to call a third function, which will have as parameters the responses of the requests of the two functions cited above.

function tradesRequest() {
  ajaxRequest(args) // args = type, url
}

function pricesRequest() {
  ajaxRequest(args)
}

function display(trades, prices) {
  // Esta função utilizará as respostas das funções acima.
}

1 answer

2


ajaxRequest cannot give synchronous feedback because ajax is asynchronous. That is a scenario like:

function ajaxRequest(type, url) {
   // etc...
   return dados; // onde dados é o valor que veio do servidor
}
var resposta = ajaxRequest('algo', 'algo');

not feasible. You have to use asynchronous logic.

To do that asynchronously you have 3 chances: callback, promises or funções assíncronas.

I leave an example, you can read much more about the possibilities in the links I indicated above.

Example:

function ajaxRequest(type, url, done) {
    const ajax = new XMLHttpRequest()

    ajax.onreadystatechange = () => {
        if (ajax.readyState === 4 && ajax.status === 200) {
            let response = parseToJson(ajax.responseText) // → JSON.parse(str)
            done(null, response);
        } else {
            done('Houve um erro!...');
        }
    }
    ajax.open(type, url)
    ajax.send()
}

ajaxRequest('clientes', '/admin.php', function(erro, resposta){
    if (erro) return console.log(erro);
    // quando esta callback correr, já vais ter a resposta disponivel
    alert(JSON.stringify(resposta, '\n', 4));
});

Edit

(to contemplate the edition in the question with 3 functions)

In this case I suggest you use Promise. You can do something like this:

function ajaxRequest(type, url, done) {
    return new Promise(function(res, rej) {
        const ajax = new XMLHttpRequest()
        ajax.onreadystatechange = () => {
            if (ajax.readyState === 4 && ajax.status === 200) {
                let response = parseToJson(ajax.responseText) // → JSON.parse(str)
                res(response);
            } else {
                rej('Houve um erro!...');
            }
        }
        ajax.open(type, url)
        ajax.send()
    });
}

function tradesRequest() {
    return ajaxRequest('foo', 'bar');
}

function pricesRequest() {
    return ajaxRequest('alfa', 'beta');
}

function display(trades, prices) {
    // Esta função utilizará as respostas das funções acima.
}

Promise.all([tradesRequest, pricesRequest]).then(function(resultados) {
    // resultados é uma array
    var resultado1 = resultados[0];
    var resultado2 = resultados[1];
    display(resultado1, resultado2);
    
    // ou ainda melhor:
    display.apply(this, resultados);
}).fail(function(e) {
    console.log(e);
});
  • I need the return of two requests to call a new function that will display the data; I tried using callbacks, but I couldn’t come up with a logic that would hold the answers to both requests. You have some guidance on how to use callbacks for this?

  • 1

    @Luanvicente if you read the links I put in the answer "master" in callbacks and asynchronous logic :) If you complete the question with the problem you have I can take a look.

  • i edited the question with a better explanation of the problem. I believe the solution is something like this your answer, but in my attempts I always have undefined as a result.

  • @Luanvicente gave one more example. Now I have to go to sleep. Good luck! If you have problems write here that help in 9 hours :)

  • thank you so much for your help!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.