NodeJS:等待直到数组被填充

NodeJS: await until array gets populated

简单的20行代码

const instaTouch = require('instatouch');
const vision = require('@google-cloud/vision');

const client = new vision.ImageAnnotatorClient();
process.env['GOOGLE_APPLICATION_CREDENTIALS']

// this returns images from instagram based on tag I provide, it returns promise.
// so far so good, I am getting the image URLs

const getMediaUrls = async (tag, limit) => {
  const options = { count: limit, mediaType: 'image' };
  const response = await instaTouch.hashtag(tag, options);
  let mediaUrls = response.collector.map((el) => el.display_url);

  if (mediaUrls !== undefined || mediaUrls.length != 0) return mediaUrls;
};

问题来了

const startScrap = (tag, labels, limit) => {
  let matchedMediaUrls = [];
  getMediaUrls(tag, limit)
    .then((mediaUrls) =>
      mediaUrls.forEach(async (mediaUrl) => {
        // send image url to google vision api and returns label
        const [result] = await client.labelDetection(mediaUrl);
        const mediaLabels = result.labelAnnotations;

       // I check if returned labels from vision api matches with any of the labels I asked for
       // if that the case I return the image, and populate matchedMediaUrls=[] array
        
       let labelsArr = mediaLabels.map((el) => el.description.toLowerCase());
        const matches = labelsArr.filter((el) => labels.includes(el));

        if (matches.length > 0) {
         // if I console.log() i find the array getting populated correctly but I don't know how to return it
          matchedMediaUrls.push(mediaUrl);
          console.log(matchedMediaUrls);
        }
      })
    )
    .catch((err) => console.log(err));
};

如果我return在这里,我得到一个空数组。

我昨天选了nodejs。这可能不是个好问题,但我真的需要帮助。我不知道如何修复它,过去 6 个小时一直在尝试。任何帮助将不胜感激。

我更改了您的功能以使用 async/await 我无法正确测试它,但如果它不起作用请告诉我

const instaTouch = require('instatouch');
const vision = require('@google-cloud/vision');

const client = new vision.ImageAnnotatorClient();
process.env['GOOGLE_APPLICATION_CREDENTIALS']

const getMediaUrls = (tag, limit) => {
    return new Promise(async (resolve, reject) => {
        const options = { count: limit, mediaType: 'image' };
        const response = await instaTouch.hashtag(tag, options);
        let mediaUrls = response.collector.map((el) => el.display_url);

        if (mediaUrls !== undefined || mediaUrls.length != 0) resolve(mediaUrls);
    });

};

这就是你调用 getMediaUrls 函数的地方


const startScrap = async (tag, labels, limit) => {

    var matchedMediaUrls = [];

    var mediaUrls = await getMediaUrls(tag, limit);


    for (let mediaUrl of mediaUrls) {

        const [result] = await client.labelDetection(mediaUrl);
        const mediaLabels = result.labelAnnotations;

        let labelsArr = mediaLabels.map((el) => el.description.toLowerCase());
        const matches = labelsArr.filter((el) => labels.includes(el));

        if (matches.length > 0) {
            matchedMediaUrls.push(mediaUrl);
            console.log(matchedMediaUrls);
        }
    }

    return matchedMediaUrls;
}