【问题标题】:Problem creating JSON data in asynchronous loop with Vuejs and FileReader使用 Vuejs 和 FileReader 在异步循环中创建 JSON 数据的问题
【发布时间】:2020-05-14 00:02:34
【问题描述】:

我有一个用户可以提交多个文件的 vue 表单组件。在将数据提交到采用 JSON 数据的远程 API 之前,我需要处理这些文件。

我尝试使用 FileReader 和异步 foreach 循环来解决这个问题,如下所示:

methods: {
  readerLoaded(geojson, date, post_data) {
    post_data.dated_profiles.push({
                  'date': date,
                  'geojson': geojson
                });
  },
  setupReader(file, date, post_data, readerLoaded) {
    var reader = new FileReader();
    reader.onload = function(e) {
      const result = JSON.parse(e.target.result);
      // Send result to callback
      readerLoaded(result, date, post_data);
    };
    reader.readAsText(file);
  },
  validate() {
    if ( this.$refs.form.validate() ) {
      /* Process GeoJSON files to POST data to API */
      const data = {
          'name': this.name,
          'index': this.index,
          'dated_profiles': Array()
      }

      const asyncLoopFunction = async (datasets, post_data, setupReader, readerLoaded) => {
        const promises = datasets.map(function (item) { return setupReader(item.file, item.date, post_data, readerLoaded); })
        return await Promise.all(promises)
      }

      asyncLoopFunction(this.datasets, data, this.setupReader, this.readerLoaded).then( () => {
        console.log('All async tasks complete!')
        console.log("After async", data)
        this.$store.dispatch('postProfile', data)
      });

    }
  }

问题是:当我将最终的 JSON 数据对象传递给 Vuex 存储操作(使用 dispatch)时,我的 dated_profiles 数组为空。

  • 如果我在异步循环完成后检查 JSON 对象,浏览器控制台会显示此 Object { name: "foo", index: "1", dated_profiles: [] }。数组看起来是空的,但是当我展开它时,我可以看到正确的完整数组……
  • 如果我将此数据传递给请求,它会告诉我我的数组肯定是空的。不应该等待所有的承诺完成吗?

我不明白为什么我的 async/await 组合不起作用,我哪里错了?

【问题讨论】:

    标签: javascript vue.js async-await


    【解决方案1】:

    您将this.setup_reader 传递给asyncLoopFunction。我认为应该是this.setupReader。

    此外,您的 setupReader 方法当前未返回承诺。您应该将其更改为:

    setupReader(file, date, post_data, readerLoaded) {
      return Promise((resolve, reject) => {
        var reader = new FileReader();
        reader.onload = function(e) {
          const result = JSON.parse(e.target.result);
          readerLoaded(result, date, post_data);
          resolve();
        };
        reader.onerror = () => reject();
        reader.readAsText(file);
      }
    },
    

    【讨论】:

    • 函数名,是我发错了,我已经更新了!感谢您的回答,我想我不明白 FileReader / async loop with promises 是如何工作的。如果我错了,请告诉我:由于 setupReader 没有返回任何内容,等待是无用的,并且在我的数组被填充之前一切都完成了,对吧?
    • 不。 async 不是没用的。但是,如果您不向Promise.all() 数组提供承诺,它就会在函数执行后立即解决(同步)。例如,现在它们是承诺,如果您删除 async 它将不起作用。你需要它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多