Из вашего кода кажется, что вы реализуете функцию для запроса Wordpress данных.
Я не думаю, что ваша проблема связана с переменной областью действия - это скорее проблема asyn c функции . Вы отправляете один AJAX запрос на страну - каждый запрос отправляется на сервер «индивидуально», обрабатывается сервером, и ответ возвращается. Ничто не гарантирует , что ответ приходит в том же порядке, в котором были отправлены запросы.
Учтите это:
const arr = []
function getSingleItem(id) {
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
.then(response => response.json())
.then(json => {
console.log(json.id)
})
}
function getAllItems() {
for (let i = 1; i < 10; i++) {
getSingleItem(i)
}
}
getAllItems()
В консоли видно, что ответы не приходят в том порядке, в котором были отправлены запросы (json.id
на самом деле является действующим числом от 1 до i
- они должны быть в порядке).
Вы должны позаботиться о заказе:
const arr = []
function getSingleItem(id) {
return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
.then(response => response.json())
.then(json => {
return json.id
})
}
async function getAllItems() {
for (let i = 1; i < 10; i++) {
const r = await getSingleItem(i)
arr.push(r)
}
console.log(arr)
}
getAllItems()
Установив async await
в функциях, я могу быть уверен, что ответы отображаются в том порядке, в котором были отправлены запросы. (await
не «пропускает» for()
l oop до go дальше, пока не придет ожидаемый ответ - что-то вроде синхронного кода.)
In в этом случае я использую функцию fetch()
, которая возвращает объект Promise
- объект, который можно ожидать редактировать в другой моей функции.
ВАШ КОД
Ваш Javascript код можно изменить:
/**
* city_selector_vars
* [
* 'countryCode' => 'NL',
* 'stateCode' => 'NL-FL',
* 'cityName' => 'A name'
* ]
* [
* 'countryCode' => 'BE',
* 'stateCode' => 'BE-BR',
* 'cityName' => 'Another name'
* ]
*/
async function get_all_state(city_selector_vars) {
if (true === Array.isArray(city_selector_vars)) {
// preparing the response array
const response_states = []
for (i = 0; i < city_selector_vars.length; i++) {
// try - catch to handle errors
try {
// await the response
const d = await get_states(city_selector_vars[i].countryCode);
// add response to the response array
response_states.push(d)
} catch (err) {
// handle error
console.log(err)
}
}
// return the array - in order!
return response_states
}
}
function get_states(countryCode, callback) {
const state_data = {
action: 'get_states_call',
country_code: countryCode
};
// console.log(state_data.country_code) shows correct country code
// returning a Promise object, so await works in the other function
return new Promise((resolve, reject) => {
$.post(ajaxurl, state_data, (response) => {
// here the wrong response first shows
// state_data.country_code is not always the same as state_data.country_code
// resolving the Promise when the response arrives
resolve(response)
});
})
}
В вашем измененном коде Promise
должен был быть явно создан (помните - fetch()
возвращает Promise
?), Поэтому он может быть обработан asyn c -await .
Я думаю, что фрагмент должен работать как есть, но если нет, то требуется только небольшая отладка:)
WORDPRESS NOTE
Если вы отправляете JSON с Wordpress, рекомендуется использовать функцию wp_send_json()
.
Подробнее: https://developer.wordpress.org/reference/functions/wp_send_json/