【问题标题】:Javascript / Vue Executing a function after another (synchronously)Javascript / Vue 一个接一个地执行一个函数(同步)
【发布时间】:2020-12-12 09:57:28
【问题描述】:

我需要在 VueJs 中一个接一个地运行一个函数

data: function() {
        return {
            stuff: '',
            myArray:[
                {
                    "id": 0,
                    "value1": 0,
                    "value2": '',
                    "etc": ''
                },
            ],
        };
},
methods: {
     fetchData() {
            axios.get('/api/get-data')
                .then(res => {
                    this.myArray = res.data;
                }).catch(err => {
                console.log(err)
            })
        },
     runThisAfterArrayPopulates(){
        /*a bunch of code that relies on the contents from this.myArray , therefore I need this.myArray to be fully populated/finalized, for example*/
       for (i = 0; i < this.myArray.length; i++) {
                /*at this point on development server this.myArray.length is 60, on production it is 1 */
                }
            }
     }
}

我目前执行这些功能如下:

created: function () {
        this.fetchData();
},
mounted: function () {
        document.onreadystatechange = () => {
          if (document.readyState == "complete") {
            console.log('Page completed with image and files to ensure it is executed at the very end')
            this.runThisAfterArrayPopulates();
          }
        }
},

在我的开发本地主机上测试时,一切都按预期运行。

一旦我作为生产应用程序上传,函数 this.runThisAfterArrayPopulates();当 this.myArray 只有一个对象而不是整个 axios 数据时运行,它没有给它足够的时间来运行。我很确定发生这种情况的原因是因为在生产服务器中我的 axios 比在我的本地主机中花费的时间更长,然后我填充了数组,并且由于 Javascript 是异步的,因此函数 runThisAfterArrayPopulates() 似乎在我的数组完全填充之前运行.

我已经阅读了有关 promises 的内容,但我不完全确定它是否适合这里。

我已尝试运行 this.fetchData();在 beforeMounted: 而不是 created: 中,我也尝试在 axios .then() 中调用 this.runThisAfterArrayPopulates() 但我仍然面临生产中长度为 1 的数组。

注意:我确信代码可以正常工作,它在开发中完美无缺,如果我创建这样的按钮:

<button @click="runThisAfterArrayPopulates()">Click me</button>

当我点击按钮时行为是完美的,所以我确信它与执行顺序有关。

【问题讨论】:

  • 您可以“存储” axios.get 返回的承诺...例如this.someStoredpromise = axios.get(....etc 并使用 this.someStoredPromise.then(this.runThisAfterArrayPopulates)

标签: javascript vue.js asynchronous vuejs2 synchronization


【解决方案1】:

如下更改您的代码。

    methods: {
         fetchData() {
                
                axios.get('/api/get-data')
                    .then(res => {
                        this.myArray = res.data;
                        this.runThisAfterArrayPopulates(); // Added method call.
                    }).catch(err => {
                    console.log(err)
                })
            },
         runThisAfterArrayPopulates(){
            /*a bunch of code that relies on the contents from this.myArray , therefore I need this.myArray to be fully populated/finalized */
         }
    },


created: function () {
        // this.fetchData();
},
mounted: function () {
        this.fetchData();
},

由于处理程序方法是一个箭头函数,这应该不会造成问题。如果您使用普通函数代替箭头函数,请注意这个问题。

编辑: 您可以尝试移动 this.fetchData();调用挂载本身。

【讨论】:

  • 我已经在您发布的内容中尝试过,并且行为相同,在开发中可以正常工作,但在生产中无法正常工作。我不得不删除“这个”。从 this.runThisAfterArrayPopulates();为了让它工作,因此我运行了 runThisAfterArrayPopulates()。执行此行时似乎执行顺序仍有问题:this.myArray = res.data;
  • @toolnin - 没有意义......如果runThisAfterArrayPopulatesmethod: 那么你真的只能使用this.runThisAfterArrayPopulates 运行它
  • 我认为 created() 被解雇了,这个 created() 对服务器进行了 ajax 调用。因此,即使在该 ajax 调用返回之前,mounted(): 也会被调用。这个执行顺序似乎有问题。删除 created(),然后将 fetchData 移至mounted()。
  • 我的错,你是绝对正确的,“这个。”是必须的。我相信您的解决方案有效。让我进一步测试一下,我会在一分钟内回复你。非常感谢!
  • 已确认,在生产中效果很好。这解决了执行顺序。再次感谢!
猜你喜欢
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
  • 2018-03-30
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多