Use closure as a function return

3

I need to use a variable of a closure as a function return to which this closure is nested. 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 that contains 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 mentioned 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.
}
    
asked by anonymous 21.12.2016 / 20:42

1 answer

2

ajaxRequest can not give synchronous return because ajax is asynchronous. In other words, a scenario like:

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

is not feasible. You need to use asynchronous logic.

To do this asynchronously you have 3 options: 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 include editing in the 3-function question)

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);
});
    
21.12.2016 / 20:52