JS async / ожидает заполнения массива ссылками с последующей загрузкой после заполнения массива

#javascript #api #promise #async-await

#javascript #API #обещаю #async-ожидает

Вопрос:

Я знаю, что об этом спрашивали несколько раз, но я все еще не могу найти решение моей конкретной проблемы. В принципе, согласно названию, я написал функцию, getLinks() которая будет заполнять глобальный массив links посредством вызовов api из SG Gov Traffic Data API.

Проблема возникает, когда я пытаюсь загрузить изображения с помощью функции, getImages() поскольку эта функция должна дождаться заполнения links массива перед запуском. Кажется, я не могу правильно использовать логику для последовательного выполнения функций.

Полный код ниже. Заранее спасибо за любые указания!

 var fs = require('fs'),
    request = require('request');

// Download individual content
function download(uri, filename, callback){
  request.head(uri, function(err, res, body){
    request(uri).pipe(fs.createWriteStream('training/'   filename)).on('close', callback);
  });
};

// Get image links from API
var links =[];

function two(n){
    return n > 9 ? ""   n: "0"   n;
}

async function getLinks() {
  links = []; // Clear the links array
  for(i = 1; i < 30; i  ) { // Loop through 30 days, chosen month is Dec 2018
    for(j = 0; j < 24; j  ) { // Loop through 24 hours each day
      request('https://api.data.gov.sg/v1/transport/traffic-images?date_time=2018-12-'   two(i)   'T'   two(j)   ':00:00', function(error, response, body) {
        if(!error amp;amp; response.statusCode == 200) {
          var parsedData = JSON.parse(body);
          links.push(parsedData.items[0]["cameras"][0]["image"].toString())
        } else {
          console.log(error)
        }
      })
    }
  }
  return;
}

// Scrape and download to directory
async function getImages() {
  await getLinks();
  for( i = 0; i < links.length; i  ) {
    download(links[i], i, function(){});
  }
}

getImages();  

Ответ №1:

getLinks возвращается до того, как он будет разрешен,

возможно, обернуть обещание вокруг вызова запроса, поместить их в массив, а затем вернуть promise.all(asyncArray)

но в настоящее время это просто

 async function getImages() {
  await undefined //getLinks();
  for( i = 0; i < links.length; i  ) {
    download(links[i], i, function(){});
  }
}
  

например:

 async function getLinks() {
    links = []; // Clear the links array
    let asyncs = []
    for(i = 1; i < 30; i  ) { // Loop through 30 days, chosen month is Dec 2018
      for(j = 0; j < 24; j  ) { // Loop through 24 hours each day
        asyncs.push(new Promise((resolve, reject) => {
            request('https://api.data.gov.sg/v1/transport/traffic-images?date_time=2018-12-'   two(i)   'T'   two(j)   ':00:00', function(error, response, body) {
            if(!error amp;amp; response.statusCode == 200) {
                var parsedData = JSON.parse(body);
                links.push(parsedData.items[0]["cameras"][0]["image"].toString())
                resolve(parsedData.items[0]["cameras"][0]["image"].toString())
            } else {
                console.log(error)
                //reject(error)
            }
            })
        }))
      }
    }
    return Promise.all(asyncs)
  }

async function getImages() {
  let _links = await getLinks();
  for( i = 0; i < links.length; i  ) {
    download(links[i], i, function(){});
  }
}
  

Комментарии:

1. Спасибо за это! Да, сейчас это работает отлично, думаю, мне все еще нужно лучше узнать async / await. 🙂