Мой совет - использовать API Promise
и fetch
.
function ajax(options) {
return new Promise(function (resolve, reject) {
fetch(options.url, {
method: options.method,
headers: options.headers,
body: options.body
}).then(function (response) {
response.json().then(function (json) {
resolve(json);
}).catch(err => reject(err));
}).catch(err => reject(err));
});
}
Вы можете использовать его следующим образом:
const ajaxResponse = await ajax({url: '/some/api/call', method: 'get'});
На случай, если вы не Уже известно, await
может использоваться только внутри функций async
. Если вы не хотите использовать функции async
, выполните следующие действия:
ajax({url: '/some/api/call', method: 'get'}).then(data => {
// process data here
});
Объяснение:
JavaScript - однопоточный язык. Это означает, что все работает в режиме блокировки. Если ваш Ajax вызов занимает 3 секунды, то JavaScript приостановится на 3 секунды. К счастью, API XMLHttpRequest
и fetch
борются с этой проблемой с помощью асинхронных функций, что означает, что код может продолжать работать, пока вызов Ajax ожидает ответа.
В вашем коде вы не получаете ответ от вашей функции, потому что вызов Ajax не останавливает выполнение, то есть к тому моменту, когда вызов сделан, уже нечего возвращать, и к тому времени, когда вызов завершен, вызов функции уже давно тоже. Однако вы можете указать JavaScript отслеживать эту асинхронную задачу через Promise
s. Когда ваша задача завершена, функция Promise
then
вызывается с данными из вызова Ajax.
JavaScript также предоставляет сахар syntacti c для упрощения чтения асинхронного кода. Когда мы используем функцию async
, мы фактически создаем обычную функцию, тело которой обернуто в Promise
.
Это также означает, что когда вы хотите дождаться результата предыдущий Promise
, вы можете добавить await
перед ссылкой Promise
и ждать завершения Promise
.
Так что у вас может быть код, который выглядит следующим образом:
const call = await ajax({ ... });
console.log(call);
, что фактически означает следующее:
ajax({ ... }).then(call => {
console.log(call);
});