2 回答
TA贡献1853条经验 获得超18个赞
从您的代码看来,您正在实现一个查询Wordpress数据的函数。
我不认为您的问题是可变范围之一-而是异步函数的问题。您向每个国家/地区发送一个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()循环更进一步——有点像同步代码。)
在这种情况下,我使用该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中,必须显式创建 a(记住 -fetch()返回 a Promise?),因此它可以由async-await处理。
我认为该片段应该按原样工作,但如果不是,那么只需要一个小调试:)
WordPress 注释
如果您使用 Wordpress 发送JSON,建议使用该wp_send_json()功能。
更多:https ://developer.wordpress.org/reference/functions/wp_send_json/
TA贡献1796条经验 获得超4个赞
至于admin_post_edit_load_states功能,我认为Promise.all是正确的方法:
function admin_post_edit_load_states() {
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 = get_states(city_selector_vars[i].countryCode);
// add response to the response array
response_states.push(d)
} catch (err) {
// handle error
console.log(err)
}
}
console.log(response_states);
Promise.all(response_states).then(function(jsonResults) {
var instance_count = 0;
for (i = 0; i < jsonResults.length; i++) {
var obj = JSON.parse(jsonResults[i]);
var len = obj.length;
var $stateValues = '';
var select_state = $('select[name*="row-' + instance_count + '"][name*="stateCode"]');
var stored_state = city_selector_vars[instance_count].stateCode;
select_state.fadeIn();
for (j = 0; j < len; j++) {
$selected = '';
var state = obj[j];
var current_state = state.country_code + '-' + state.state_code;
if (current_state === stored_state) {
$selected = ' selected="selected"';
}
var selected = $selected;
$stateValues += '<option value="' + state.country_code + '-' + state.state_code + '"' + selected + '>' + state.state_name + '</option>';
}
select_state.append($stateValues);
instance_count++;
}
});
}
}
这应该在异步的同时保持原始顺序。注意我们在这里做什么:
首先,我们response_states用 Promise 填充数组(每次调用 get_states 都会返回一个 Promise)。然后,Promise.all(response_states)创建一个新的 Promise,当 response_states 数组中的所有 Promise 都被解决时,该 Promise 将被解决。最后,参数 jsonResults 是一个数组,其中包含数组中每个已解析承诺的对应值response_states。
让我们看看它是否有效。
添加回答
举报