Как вернуть ответ из XMLHttpRequest?

Я отправляю запрос:
var xhr = new XMLHttpRequest();
	xhr.open("POST", url, true);
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	var text='empty';

	xhr.onreadystatechange = function() {
	  if (this.readyState === 4) {
	    if (this.status >= 200 && this.status < 400) {
	      	var r=JSON.parse(this.responseText);
  			text=r.text[0]
  			console.log(text); //result
	    } else {
	      // Error :(
	    }
	  }
	};
	xhr.send();
	return text; // вернул empty :(


Но возвращает сначала text со значение 'Empty', только потом уже значением от запроса. Как реализовать чтобы сразу возвращал то значение которое получил от запроса?
  • Вопрос задан
  • 4372 просмотра
Решения вопроса 2
alexey-m-ukolov
@alexey-m-ukolov Куратор тега JavaScript
Из асинхронной функции невозможно вернуть значение, потому что на момент выхода из неё оно ещё не определено.
Вы можете:
  1. Вернуть промис, который будет возвращать значение
  2. Принимать в асинхронную функцию другую функцию и вызывать её при получении результата, передавая его в качестве аргумента.
  3. Сделать запрос синхронным и писать результат в глобальную переменную.
  4. Использовать синтаксис async/await, если у вас свежая версия Node.

Первый вариант более современный и гибкий, второй более простой для понимания. По обоим вариантам есть масса информации, документации и уроков (подобный вопрос задаётся здесь ежедневно не по разу, поэтому не расписываю подробнее).
Третий вариант - кривой костыль и приведён только для полноты картины, не стоит так делать.
Чётвертый - это промисы для хипстеров, лучше использовать его тогда, когда вы хорошо умеете работать с промисами, чтобы случайно ничего себе не отстрелить.
Ответ написан
Комментировать
DexterHD
@DexterHD
Software Engineer, Teamlead, CTO
Js работает асинхронно. В тот момент когда вы делаете return text;, запрос еще не ушел. Т.е. событие onreadystatechange еще не сработало. Здесь можно использовать Promise.

// Оборачиваем код в функцию, которая вернет Promise.
let xmlHttpRequest = function() {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    var text='empty';
    xhr.onreadystatechange = function() {
      if (this.readyState === 4) {
        if (this.status >= 200 && this.status < 400) {
          var r=JSON.parse(this.responseText);
          text=r.text[0];
          resolve(text); // Вызываем resolve и передаем text в качестве параметра
        } else {
          reject(new Error('Error')); // Обработка ошибки
      }
     }
    };
    xhr.send();
  });
};

xmlHttpRequest()
  .then(function(text){
  console.log(text);
}).catch(function(err){
  console.error(err);
});
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы