Правильна робота із запитами Ajax у WordPress
Щоразу, коли ви працюєте зі сторонніми API і робите це в асинхронному режимі, завжди є ймовірність того, що будь-який запит, який ви запитує, поверне небажаний результат.
Можливо, це код помилки, можливо, це попередження, а може, це просте повідомлення, яке говорить щось на кшталт «Ми все ще обробляємо ваш запит».
У кожному разі ви зазвичай можете нормально впоратися з ними на стороні сервера, і дозволити стороні клієнта знати, як це впоратися. Але якщо ви маєте справу з останнім випадком, саме тут вас заблокує стороння обробка; є інші речі, які ви можете зробити, щоб краще впоратися з цією ситуацією.
Наприклад, в останньому випадку краще трохи почекати, а потім знову зробити запит, щоб побачити, чи API має для вас іншу відповідь.
Але для цього потрібен Ajax, який, очевидно, вимагає JavaScript. Одним із очевидних, але більш застарілих методів зробити це є використання setInterval.
Однак проблема полягає в тому, що він створює стек запитів, а потім, коли відповідь буде готова, кожен елемент у стеку отримає однакову відповідь.
Це може серйозно вплинути на будь-який сервер. І є кращі способи зробити це.
Правильна робота із запитами Ajax
Як зазвичай, оскільки WordPress поставляється з jQuery, я буду використовувати його; однак я також закликаю вас — якщо ви ще цього не зробили — переглянути Ajax у ES6, щоб отримати уявлення про те, як це зробити нативно.
У будь-якому випадку, ідея полягає в наступному: замість того, щоб встановлювати певний інтервал, використовуйте вбудовані функції Ajax, щоб правильно оцінити відповідь. І лише за певних умов запускати функцію знову.
Приклад: метод $.post jQuery пропонує деякі функції, які можна використовувати саме для цього. Наприклад, він пропонує такі методи, як:
- зроблено()
- невдача()
- завжди()
І кожен із них призначений для виконання за певних умов, які я зараз покажу в деяких зразках коду.
Однак перед тим, як це зробити, важливо розуміти, що я надсилаю кілька параметрів, з якими я припускаю, що ви знайомі:
- URL-адресу WordPress Ajax (яку я визначу як acme.ajax_url),
- URL-адресу допису, який ми переглядаємо (який зберігатиметься в змінній sUrl),
- і одноразовий номер безпеки, який я буду називати acme.security
Якщо щось із наведеного вище не зрозуміло, прочитайте посилання на сторінки, щоб побачити, як це досягається.
Але з урахуванням сказаного, ось ідея, яка лежить в основі того, як можна керувати повторюваними відповідями Ajax без setInterval.
1 Функція для роботи
Перше, що вам потрібно зробити, це обернути роботу, яку ви збираєтеся виконувати, у її власну функцію. Це означає, що ви можете викликати його з будь-якого іншого місця в клієнтській програмі або навіть у контексті таймера (якщо це абсолютно необхідно).
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// ...
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ..
});
}
І, як ви бачите, я пішов вперед і викреслив деякі функції, про які згадував вище.
2 Досягніть успіху
У разі успіху ви можете використовувати анонімну функцію як зворотний виклик для функції $.post. Основним аргументом, який вас повинен хвилювати, є аргумент відповіді .
Як правило, мені подобається, щоб моя відповідь мала атрибут успіху та атрибут невдачі. Це полегшує обробку випадку, коли відповідь повністю успішна, але дані, які повертаються із сервера, не відповідають очікуванням.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ...
});
}
Це не обов’язково означає, що стався збій. Це просто означає, що те, що я шукав, не було знайдено.
3 Подолайте невдачу
З іншого боку, бувають випадки, коли щось може вийти з ладу. Чому це відбувається може бути з будь-якої кількості причин, і щоб правильно це зрозуміти, варто перевірити аргументи, які надає зворотний виклик, а саме статус і помилку.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
cosole.log(error);
})
.always(function() {
// ...
});
}
Я не можу навести тут конкретні приклади, оскільки кожен API відрізняється; однак я рекомендую принаймні записувати дані на консоль, щоб ви могли зрозуміти, що відбувається, і як ви можете витончено впоратися з цим на рівні коду.
4 Обробка безумовного випадку
У цьому конкретному випадку ця функція запускатиметься незалежно від того, було щось успішно чи ні.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Ця функція не є те, що вам може знадобитися завжди (без каламбуру), але це надійний варіант, щоб, скажімо, приховати панель виконання або відобразити щось в інтерфейсі користувача. Це може дати користувачеві трохи відгуку про те, що запит завершив свою роботу (знову ж таки, незалежно від невдачі чи успіху).
5 Знову домагайтеся успіху
Нарешті, метод done дуже схожий на метод успіху, але думайте про нього як про призначений для повторного виклику.
Це означає, що після того, як відповідь повернеться від сервера з аргументом відповіді, те саме запуститься знову, коли все інше буде завершено.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// Display any additional changes you may want to make based on the respnse.
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Це дає вам ще один шанс зробити все, що ви хочете зробити з аргументом відповіді ще раз, перш ніж усе буде завершено.
Я рідко використовую це, але були випадки, коли я хотів видалити елемент лише після того, як щось було зроблено, усі інші обробки виконано, і відповідь була успішною.
Можливо, вам все це не потрібно
Очевидно, що більша частина коду вище призначена лише для демонстрації того, як обробляти запити. Але мета полягає в тому, щоб показати, як обробляти запит без необхідності встановлювати інтервали для стеку запитів. Замість цього ви користуєтеся перевагами вже існуючих функцій, щоб, скажімо, знову викликати функцію, якщо сталася помилка.
У будь- якому випадку, це може бути надмірним для деяких, але для інших, які звикли використовувати setInterval, це може бути набагато кращим способом керування запитами Ajax, які не складаються і не запускають той самий запит на сервер, коли відповідь уже надійшла. керований.
І, зрештою, це мета: ефективний код, який отримує потрібну нам інформацію, не перешкоджаючи сторонньому API чи браузеру нашого власного користувача.
