#javascript #ajax #asynchronous #async-await
#javascript #ajax #асинхронный #асинхронное ожидание
Вопрос:
По какой-то причине мой асинхронный вызов работает не так, как ожидалось. Вот что я пытаюсь сделать:
- Выполните несколько вызовов ajax в цикле
- В случае успеха отправьте некоторые данные API в глобальный массив
- Используйте этот массив в другой функции (например, распечатайте его)
var authcodes = ["E06000001","E06000002","E06000003"];
var dict = [];
async function ajaxCall() {
for(var i=0;i<authcodes.length;i ){
$.ajax({
type: "GET",
url: 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaCode=' authcodes[i] 'amp;structure={"areaCode":"areaCode","cumCasesByPublishDate":"cumCasesByPublishDate"}',
dataType: "json",
success: function(data) {
dict.push(data.data[0].cumCasesByPublishDate);
}
});
} return dict;
}
async function printArr () {
const someApiRes = await ajaxCall()
console.log(someApiRes[1]); //this doesn't work
console.log(dict[1]); //this doesn't work
}
printArr();
Вот JSFiddle с прокомментированным кодом: https://jsfiddle.net/gjv9hrpo/1 /
Я понимаю, что printArr()
функция должна запускаться после заполнения массива из-за async
характера, который, как я надеялся, решит ожидание. Я использую это неправильно?
Спасибо.
Комментарии:
1. Вы ничего не
await
делаете в стороне отajaxCall
2. Ваша функция ajaxCall является асинхронной, но она не ожидает используемый вами метод $.ajax.
3. Попробуйте сделать ajaxCall обещанием, которое разрешается при срабатывании успешного обратного вызова. Вот пример: javascript.info/promise-basics
4. Просто используйте
fetch()
вместо этого, он уже возвращает обещание, и получение JSON очень просто для загрузки.5. Потрясающе!
await $.ajax({..
я считаю, что это должно быть сделано!
Ответ №1:
Используйте обещание.Все ()
async function ajaxCall() {
var promises = [];
for(var i=0;i<authcodes.length;i ){
promises.push($.ajax({
type: "GET",
url: 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaCode=' authcodes[i] 'amp;structure={"areaCode":"areaCode","cumCasesByPublishDate":"cumCasesByPublishDate"}',
dataType: "json",
success: function(data) {
dict.push(data.data[0].cumCasesByPublishDate);
}
}));
}
await Promise.all(promises);
return dict;
}
Комментарии:
1. Вы все еще забыли использовать
await
ключевое слово.
Ответ №2:
Возможно, имеет смысл сделать это с помощью promises.
Promise.all позволяет узнать, когда либо все входные обещания выполнены, либо когда одно из них отклоняется.
var authcodes = ["E06000001", "E06000002", "E06000003"];
function ajaxCalls() {
return Promise.all(
authcodes.map((code) => {
return new Promise(async (resolve) => {
const response = await fetch(
`https://api.coronavirus.data.gov.uk/v1/data?filters=areaCode=${code}amp;structure={"areaCode":"areaCode","cumCasesByPublishDate":"cumCasesByPublishDate"}`
)
const json = await response.json();
resolve(json.data[0].cumCasesByPublishDate);
});
})
);
}
function printArr() {
ajaxCalls().then((values) => {
console.log(values);
}).catch(e => {
console.error(e)
});
}
printArr();
Promise.allSettled выдает вам сигнал, когда все входные обещания выполнены, что означает, что они либо выполнены, либо отклонены. Это полезно в тех случаях, когда вас не волнует состояние обещания, вы просто хотите знать, когда работа будет выполнена, независимо от того, была ли она успешной.
var authcodes = ["E06000001", "E06000002", "E06000003"];
function ajaxCalls() {
return Promise.allSettled(
authcodes.map((code, i) => {
return new Promise(async (resolve, reject) => {
if (i ===0 ) reject('something went wrong')
const response = await fetch(
`https://api.coronavirus.data.gov.uk/v1/data?filters=areaCode=${code}amp;structure={"areaCode":"areaCode","cumCasesByPublishDate":"cumCasesByPublishDate"}`
);
const json = await response.json();
resolve(json.data[0].cumCasesByPublishDate);
});
})
);
}
async function printArr() {
const results = await ajaxCalls();
console.log(results.map((result) => result.value || result.reason));
}
printArr();