JS async / await заполнение массива ссылками, затем загрузка после заполнения массива - PullRequest
1 голос
/ 15 марта 2019

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

Проблема возникает, когда япопробуйте загрузить изображения с помощью функции 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) + '%3A00%3A00', function(error, response, body) {
        if(!error && 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 Ответ

0 голосов
/ 15 марта 2019

getLinks возвращает до разрешения,

возможно, обернуть обещание вокруг вызова запроса, поместить их в массив и затем вернуть обещание. Все (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) + '%3A00%3A00', function(error, response, body) {
            if(!error && 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(){});
  }
}
...