@FernandoErrNando

Почему не работает await в данном случае?

Приветствую, друзья. Недавно начал изучать Ноду, в качестве обучающего задания придумал написать асинхронный многопоточный парсер с ограничением кол-ва одновременных загрузок. В связи с этим вопрос: Почему данный код выполняется правильно (т.е. асинхронно, результаты выдаются после прихода всех данных с апи), а во втором случае, с ограничением числа загрузок - в ответ возвращается массив промисов?

Работает
const axios = require('axios');
//It works
async function go2() {
  try {
    console.time('1st');
    const urls = [
            {
                'url': 'https://randomuser.me/api',
                'method': 'get'
            },
            {
                'url': 'https://uinames.com/api',
                'method': 'get'
            }];
    var promises = await urls.map(async function (currentValue, index, array) {
        return axios(currentValue);
    });
    
    // await all three promises to come back and destructure the result into their own variables
    var array = await Promise.all(promises).catch(function(err) {
        console.log(err.message); // some coding error in handling happened
      });;
      
    const results=array.map(function (currentValue, index, array) {
        return currentValue.status;
    });
    console.log(results);
    console.timeEnd('1st');
        return results;
  } catch (e) {
    console.error(e); // 
  }
}

go2();

Не работает
async function go3() {
  try {
    console.time('1st');
    const MAX_SIMULTANEOUS_DOWNLOADS = 2;

    const urls = [
        {
            'url': 'https://stats.nba.com/stats/teamyearbyyearstats?LeagueID=00&SeasonType=Playoffs&TeamID=1610612759&PerMode=PerGame', 
            'method':'get'
        },
        {
            'url': 'https://api.github.com/users/wesbos', 
            'method':'get'
        },
        {
            'url': 'https://randomuser.me/api', 
            'method':'get'
        },
        {
            'url': 'https://uinames.com/api', 
            'method':'get'
        }
    ];
    let subarray = []; //массив в который будет выведен результат.
    // Разбиваем массив на чанки, чтобы сразу все ссылки не грузить за один заход
    for (let i = 0; i <Math.ceil(urls.length/MAX_SIMULTANEOUS_DOWNLOADS); i++){
        subarray[i] = urls.slice((i*MAX_SIMULTANEOUS_DOWNLOADS), (i*MAX_SIMULTANEOUS_DOWNLOADS) + MAX_SIMULTANEOUS_DOWNLOADS);
    }

   //Здесь должен по идее сработать await, но нет.
    var dataFromRequest =await  subarray.map(async function (currentValue, index, array) {
        var promises = await currentValue.map(async function (currentValue1, index1, array) {
            return axios(currentValue1);
        });
        
        // await all three promises to come back and destructure the result into their own variables
        var responses=await Promise.all(promises).catch(function(err) {
            console.log(err.message); // some coding error in handling happened
          });
        
        const results=await responses.map(function (currentValue1, index1, array) {
            console.log(index1, currentValue1.data); // some coding error in handling happened
            return currentValue1.status;
        });
        return results;
    });
    console.log(dataFromRequest);
    console.timeEnd('1st');
    return dataFromRequest;
  } catch (e) {
    console.error(e); // 
  }
}
go3();


Ответ от сервера:
[ Promise { }, Promise { } ]
  • Вопрос задан
  • 94 просмотра
Решения вопроса 1
@FernandoErrNando Автор вопроса
Правильный ответ, который подсказали на другом ресурсе: await должен применяться к Promise, Поэтому array.map нужно обернуть в промис (например передать его, например, в Promise.all) и уже к результату применить await.
async function go3() {
  try {
    console.time('1st');
    const MAX_SIMULTANEOUS_DOWNLOADS = 2;

    const urls = [
        {
            'url': 'https://stats.nba.com/stats/teamyearbyyearstats?LeagueID=00&SeasonType=Playoffs&TeamID=1610612759&PerMode=PerGame', 
            'method':'get'
        },
        {
            'url': 'https://api.github.com/users/wesbos', 
            'method':'get'
        },
        {
            'url': 'https://randomuser.me/api', 
            'method':'get'
        },
        {
            'url': 'https://uinames.com/api', 
            'method':'get'
        }
    ];
    let subarray = []; //массив в который будет выведен результат.
    // Разбиваем массив на чанки, чтобы сразу все ссылки не грузить за один заход
    for (let i = 0; i <Math.ceil(urls.length/MAX_SIMULTANEOUS_DOWNLOADS); i++){
        subarray[i] = urls.slice((i*MAX_SIMULTANEOUS_DOWNLOADS), (i*MAX_SIMULTANEOUS_DOWNLOADS) + MAX_SIMULTANEOUS_DOWNLOADS);
    }
    var dataFromRequest = await Promise.all(subarray.map(async function (currentValue, index, array) {
        var promises = currentValue.map(async function (currentValue1, index1, array) {
            return axios(currentValue1);
        });

        // await all three promises to come back and destructure the result into their own variables
        var responses = await Promise.all(promises).catch(function (err) {
            console.log(err.message); // some coding error in handling happened
        });

        const results = responses.map(function (currentValue1, index1, array) {
            console.log(index1, currentValue1.data); // some coding error in handling happened
            return currentValue1.status;
        });
        return results;
        })
    );
    console.log(dataFromRequest);
    console.timeEnd('1st');
    return dataFromRequest;
  } catch (e) {
    console.error(e); // 
  }
}

go3()
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы