Как использовать JS async / await для ожидания ответа AJAX

myList = [[1]*4] * 3 создает один объект списка [1,1,1,1] в памяти и копирует его ссылку 3 раза. Это эквивалентно obj = [1,1,1,1]; myList = [obj]*3. Любая модификация obj будет отражена в трех местах, где obj упоминается в списке. Правильным утверждением будет:

myList = [[1]*4 for _ in range(3)]

или

myList = [[1 for __ in range(4)] for _ in range(3)]

. Важно отметить, что * оператор в основном используется для создания список литералов. Поскольку 1 является литералом, значит, obj =[1]*4 создаст [1,1,1,1], где каждый 1 будет атомарным, а не ссылкой 1, повторяемым 4 раза. Это означает, что если мы obj[2]=42, то obj станет [1,1,42,1] не [42,42,42,42], как могут предположить некоторые.

0
задан Philosophist 24 March 2019 в 07:18
поделиться

3 ответа

Здесь две вещи: - Ваша getRecord функция не возвращает Promise, поэтому ожидание ничего не ждет - forEach не может работать с асинхронными функциями, так как реализация не ожидает.

Для первой проблемы вы можете решить ее, выполнив:

async function getRecord(cell_date) {
    return $.ajax({
        url: 'rec/getRecord/'+cell_date,
        type: 'get',
        dataType: 'json',
    })
    .then(response => response.data);
}

Для второй проблемы вы можете сделать это, выполнив цикл следующим образом:

async function testAsyncAwaitFunction() {
    let layerNames = await getCellLayers();
    for (layerName of layerNames) {

        cell_date = layerName.substring(3)+"_"+window['currentImage'].substring(17,25);
        console.log(cell_date+":");
        let cellRecord = await getRecord(cell_date);
        console.log("Matches: "+cellRecord.length);
        console.log("testAsyncAwaitFunction response: "+JSON.stringify(cellRecord));

    }
}
[1110 ] Но при этом все запускается один за другим. Вы могли бы сделать еще лучше, отправив запросы, а затем дождавшись завершения всех из них, используя Promise.all следующим образом:

const promises = []
for (layerName of layerNames) {
        cell_date = layerName.substring(3)+"_"+window['currentImage'].substring(17,25);
        console.log(cell_date+":");
        promises.push(getRecord(cell_date));
}
const records = await Promise.all(promises)
0
ответ дан François P. 24 March 2019 в 07:18
поделиться

Что нужно помнить об асинхронности, так это о том, что любая функция с добавленной асинхронностью должна возвращать Обещание. getRecord должен вернуть то, что у вас есть. Кроме того, в то время как ваша внешняя функция testAsyncAwaitFunction является асинхронной, а ваш обратный вызов forEach - асинхронным, у вас нет ничего ожидающего разрешения ВСЕХ обещаний вашего forEach.

Вы хотите этот шаблон:

async function testAsyncAwaitFunction() {
    let layerNames = await getCellLayers();
    const promises = [];
    layerNames.forEach(function(layerName) {
        promises.push(getRecord(cell_date));
    });
    const cell_records = await Promise.all(promises);
    cell_records.forEach(function(cell_record, idx) {
        cell_date = layerNames[idx].substring(3)+"_"+window['currentImage'].substring(17,25);
        console.log(cell_date+":");
        console.log("Matches: "+cellRecord.length);
        console.log("testAsyncAwaitFunction response: "+JSON.stringify(cellRecord));
    })
}
0
ответ дан chris 24 March 2019 в 07:18
поделиться

замените getRecord на это

function getRecord(cell_date) {
    return $.ajax({
        url: 'rec/getRecord/'+cell_date,
        type: 'get',
        dataType: 'json'
    }).then(function(response){
      console.log("getRecord response: "+JSON.stringify(response));
      return response['data'];
  });
}

И удалите оба ключевых слова async и await из любого места в вашем коде, кроме testAsyncAwaitFunction в этих двух частях:

[ 1111] async function testAsyncAwaitFunction()

и

let cellRecord = await getRecord(cell_date);

В противном случае они вам не нужны.

Раньше это не работало, потому что ваша функция должна возвращать обещание, содержащее данные. Вы должны прочитать об обещаниях JavaScript . Async / Await является в значительной степени синтаксическим сахаром для них и используется для обработки асинхронного кода. Единственный действительный асинхронный код, который у вас есть, это вызов getRecord.

0
ответ дан ceckenrode 24 March 2019 в 07:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: