首页 > 解决方案 > 在 Promise 中将数据异步写入 GCS

问题描述

我正在尝试找到一种将 json 数据写入 Google Cloud Storage 存储桶中的文件的方法,在承诺中。

我发现的是,如果我尝试将 .push() 值一个一个地放入一个数组然后返回它,它只会给我来自数组的前 3 个结果(而 console.log 将返回所有内容)。

如果我尝试在本地范围内写一些东西,它只会返回数组中的最后一个值(并覆盖所有以前的值而不是附加它们)。

所以基本上我的问题是:有没有办法编写一个承诺或类似的东西来等待所有循环的值被收集起来,一旦完成,将这些值返回给一个函数,然后将它们全部上传到 GCS?

或者有没有一种方法可以在抓取数据的同时将这些值异步写入 GCS 中的 .json 文件?

const urls = [/* 20+ URLs go here... */];
let promises = [];

// Build array of Promises
urls.map(function(url) {
  promises.push(axios.get(url));
});

// Map through the array of promises and get the response results
axios.all(promises).then((results) => {
  results.map((res) => {
    try {
      // Scrape the data
      const $ = new JSDOM(res.data);
      const data = {};

      data.title = ($.window.document.querySelector('head > title') !== null ? $.window.document.querySelector('head > title').text : '');
      data.description = ($.window.document.querySelector("meta[name='description']") !== null ? $.window.document.querySelector('meta[name="description"]').content : '');
      data.robots = ($.window.document.querySelector("meta[name='robots']") !== null ? $.window.document.querySelector("meta[name='robots']").content : '');

      const value = JSON.stringify(data) + '\n';

      // Tried array.push(value) here but doesn't return all the values?
      // Any way to return all the values and then bulk upload them to GCS outside of this code block?
      const file = storage.bucket(bucketName).file(filename);
      file.save(value, function(err) {
        if (!err) {
          // file written
        }
      })

    } catch(e) {
      console.log(e);
    }
  })
})

抱歉解释不好,基本上我不能将所有值推送到数组然后上传,如果我尝试一个一个上传值,我只能得到循环数组中的最后一个值。

注意:我没有尝试使用 fs.writeFile() 将数据保存到本地的 .json 文件,然后上传到 GCS,而是将 JSON 数据直接发送到 GCS,而无需中间的步骤。

标签: javascriptnode.jsgoogle-cloud-storage

解决方案


如果我正确理解你需要什么它应该工作

axios.all(promises).then((results) => {
  const uploads = results.map((res) => {
    try {
      // Scrape the data
      const $ = new JSDOM(res.data);
      const data = {};

      data.title = ($.window.document.querySelector('head > title') !== null ? $.window.document.querySelector('head > title').text : '');
      data.description = ($.window.document.querySelector("meta[name='description']") !== null ? $.window.document.querySelector('meta[name="description"]').content : '');
      data.robots = ($.window.document.querySelector("meta[name='robots']") !== null ? $.window.document.querySelector("meta[name='robots']").content : '');

      const value = JSON.stringify(data) + '\n';

      return new Promise((resolve, reject) => {
       const file = storage.bucket(bucketName).file(filename);
       file.save(value, function(err) {
         if (!err) {
           resolve()
         }
         reject()
       })
      });


    } catch(e) {
      console.log(e);
    }
  })
  return Promise.all(uploads);
})

推荐阅读