首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在等待承诺完成时在Vue.js中获取DOM更新时遇到困难

在等待承诺完成时在Vue.js中获取DOM更新时遇到困难
EN

Stack Overflow用户
提问于 2019-11-13 00:02:14
回答 3查看 1.6K关注 0票数 3

我不是超级精通JS的承诺,虽然我通常知道足够危险。我正在研究Vue方法,该方法处理this.data()中存在的大型数据对象的搜索--通常,当我通过axios发出异步请求时,这种格式工作得很好,但在这种情况下,我必须手动创建一个承诺来获得所需的行为。下面是代码的示例:

代码语言:javascript
复制
        async searchPresets() {

            if (this.presetSearchLoading) {
                return
            }

            this.presetSearchLoading = true; // shows spinner
            this.presetSearchResults = []; // removes old results
            this.selectedPresetImports = []; // removes old user sections from results

            // Need the DOM to update here while waiting for promise to complete
            // otherwise there is no "loading spinner" feedback to the user.
            const results = await new Promise(resolve => {

                let resultSet = [];
                for (var x = 0; x < 10000; x++) {
                    console.log(x);
                }

                let searchResults = [];
                // do search stuff
                resolve(searchResults);

            });

            // stuff after promise

        }

问题是,承诺后的东西是正确的。它在执行之前等待解析,并按应有的方式接收适当的搜索结果数据。

问题是DOM在发布承诺时不会更新,所以UI就在那里。

有人知道我做错了什么吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-11-13 17:45:33

所以,当我说,“我并不精通JS的承诺,虽然我知道的足够危险。”

我很感激帮助我度过难关的种种努力,但事实证明,做出承诺并不意味着它本身就是不合时宜的。这是我的错。问题不在于Vue没有更新DOM,问题在于允诺代码正在同步执行和阻塞--因此,因为执行从来没有停止等待,Vue没有更新DOM的权限。

一旦我将我的承诺代码封装在一个setTimout(() => { /* all code here then: */ resolve(searchResults); }, 200);中,一切都开始工作了。我猜设置的超时允许执行足够长的时间,使vue能够根据我以前的数据更改更改dom。脚本仍然在技术上阻止UI运行,但至少在这个过程中,我的加载程序正在旋转,这对我在这里所做的工作来说已经足够好了。

请参阅:Are JavaScript Promise asynchronous?

票数 1
EN

Stack Overflow用户

发布于 2019-11-13 00:50:38

试试$nextTick()

Vue 2.1.0+:

代码语言:javascript
复制
const results = await this.$nextTick().then(() => {                      
  let resultSet = []
  for (var x = 0; x < 10000; x++) {
    console.log(x)
  }

  let searchResults = []
  // do search stuff
  return searchResults
});

任何Vue:

代码语言:javascript
复制
const results = await new Promise(resolve => {                      
  this.$nextTick(() => {
    let resultSet = []
    for (var x = 0; x < 10000; x++) {
      console.log(x)
    }

    let searchResults = []
    // do search stuff
    resolve(searchResults)
  })
})
票数 3
EN

Stack Overflow用户

发布于 2019-11-13 06:34:12

Vue将查找数据更改,并将它们收集到数组中,以判断DOM是否需要在以后重命名。这意味着Vue中的所有内容都是事件(数据)-driven。您的函数只定义没有数据绑定到V的行为。因此,Vue引擎将什么也不做,因为它们的依赖数据集中没有任何变化。

我看到您的承诺函数将解析对变量"searchResults“的响应。如果DOM使用该变量,则Vue引擎将在承诺完成后收集更改。您可以将属性放在"data()“中,并将其绑定到DOM。

例如:

代码语言:javascript
复制
<span v-for="(res, key) in searchResults" :key="key">
  {{ res.name }}
</span>
...
<script>
  export default {
    ...
    data () {
      return { searchResults: [] }
    },
    ...
  }
</script>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58828474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档