V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Rexxar
V2EX  ›  JavaScript

请教关于 JS 的 await 的问题,应该没那么幼稚

  •  
  •   Rexxar · 2020-01-16 15:37:50 +08:00 · 3454 次点击
    这是一个创建于 1781 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司就我一个开发,后端被逼成了全干,现在前端越来越复杂,头大。

    找了个 VUE 的模板。echarts 想用 ydata 接收后端传来的值,定义了取值的方法 fetchData,因为是 axios 异步的,在 drawLine 调用 await 修饰的 fetchData,然而 console.log ydata 是空的,感觉是一个 await 不管用,还有 then 的影响没消除。 但是我不调用 fetchData(),直接在 drawLine()里面使用 await this.$axiso.post(...),却成功给 ydata 赋值了。看起来跟直接调用 fetchData 没什么区别,理解不了。

    methods: { fetchData() { this.$axios .post("/controllermsgdatelist", this.listQuery) .then(response => { this.ydata = response.data.result; }); },

    async drawLine() {
      await this.$axios
        .post("/controllermsgdatelist", this.listQuery)
        .then(response => {
          this.ydata = response.data.result;
        });
    
      // await this.fetchData();
    
      console.log(this.ydata);
    

    }

    22 条回复    2020-01-18 16:25:51 +08:00
    runhua
        1
    runhua  
       2020-01-16 15:40:38 +08:00 via Android
    好久没写 js,好像是
    let res = await this.$axios
    .post("/controllermsgdatelist", this.listQuery)


    console.log(res);
    }
    结果从 res 里面取
    Sapp
        2
    Sapp  
       2020-01-16 15:41:50 +08:00   ❤️ 1
    你的 fetchData 方法没有把异步 return 出来

    fetchData() {
    return this.$axios.get('/xxx')
    }

    async drawLine() {
    const res = await this.fetchData()
    console.log(res)
    }

    这样应该是没问题的
    scyangjian
        3
    scyangjian  
       2020-01-16 15:43:51 +08:00
    B 站搜全栈之巅可以看看他的是怎么写的
    fishlium
        4
    fishlium  
       2020-01-16 15:44:02 +08:00   ❤️ 1
    fetchData 改成
    ````
    async fetchData() {
    const res = await this.$axios.post("/controllermsgdatelist", this.listQuery);
    this.ydata = res.data.result;
    }
    ````
    wangyzj
        5
    wangyzj  
       2020-01-16 15:46:02 +08:00
    别问为什么
    干就是了
    zhw2590582
        6
    zhw2590582  
       2020-01-16 15:49:13 +08:00
    看看 this.ydata 的赋值过程是不是异步的,异步的话可能引起空值
    zhw2590582
        7
    zhw2590582  
       2020-01-16 15:51:27 +08:00
    async drawLine() {
    this.ydata = await this.$axios
    .post("/controllermsgdatelist", this.listQuery)
    .then(response => response.data.result);

    console.log(this.ydata);
    }
    Hypn0s
        8
    Hypn0s  
       2020-01-16 15:53:47 +08:00
    二楼正解

    ```javascript

    fetchData() {
    return this.$axios
    .post("/controllermsgdatelist", this.listQuery)
    .then(response => {
    this.ydata = response.data.result;
    });
    }

    ```
    shintendo
        9
    shintendo  
       2020-01-16 15:55:27 +08:00
    2L 说的对,你就是没把 promise return 出来
    wu67
        10
    wu67  
       2020-01-16 16:00:34 +08:00
    其实就是没 return...而且不用 async 都行吧, 直接 promise then 更加无脑, 看起来更像是同步
    shintendo
        11
    shintendo  
       2020-01-16 16:01:37 +08:00
    其实很简单,你把 this.$axios.post(...).then(...)这个表达式记为变量 x,再对比一下你的两个写法:

    fetchData() {x}
    await fetchData()

    await x

    就能一眼看出差异了
    mikoshu
        12
    mikoshu  
       2020-01-16 16:04:44 +08:00
    await 需要 return 一个 promise
    ashong
        13
    ashong  
       2020-01-16 16:05:17 +08:00 via iPhone
    外面再套一个 promise
    hyzzz
        14
    hyzzz  
       2020-01-16 16:05:17 +08:00
    2 楼说的对,await 后面跟着 promise
    star7th
        15
    star7th  
       2020-01-16 16:05:41 +08:00
    这个好像是 axios 源码设计如此。后面有 then 和没有 then 返回的东西不一样。它是为了兼容 await 的写法和早前流行的 then 写法。你选择其中一个方式去做就好。不要两个一起来
    star7th
        16
    star7th  
       2020-01-16 16:07:27 +08:00
    好像我没讲对。总是这两种方式只选择一种来用就是了。
    shintendo
        17
    shintendo  
       2020-01-16 16:23:13 +08:00
    @star7th async/await 和 Promise 一起用没有任何问题,有些场景只用 async/await 实现不了,必须混用 Promise.

    把 await 理解为“本句以下直到函数末尾的内容全部放入一个隐藏的 then”就不会晕车了
    Rexxar
        18
    Rexxar  
    OP
       2020-01-16 17:13:47 +08:00
    @Sapp
    @shintendo

    加了 return 确实对了
    但是 ydata 的赋值操作放在了 fetchData 里。即时不 return,这条指令该执行也要执行啊。 比如我有个 table,赋值也放在了 fetchData 里,this.tablelist = response.data.result。 页面的 table 确实显示数据,所以这个 return 不是让本来不会返回的值返回,而是让执行顺序提前了?
    azcvcza
        19
    azcvcza  
       2020-01-16 18:31:30 +08:00
    async 和 await 其实是 promise 的语法糖来着
    shintendo
        20
    shintendo  
       2020-01-16 18:41:43 +08:00   ❤️ 1
    @Rexxar 你可能想的太复杂了
    > 即时不 return,这条指令该执行也要执行啊
    是的,这条指令执行了,问题在于 await 没有正确地等待这条指令执行完,即 await 等待的目标不对。
    await fetchData()这条语句,await 的对象是 fetchData(),即 fetchData 函数调用的返回值,而你没有返回任何东西,相当于 await undefined;
    Vogan
        21
    Vogan  
       2020-01-16 23:54:52 +08:00
    既然用 async/await 了,就都用,别一会又 Promise 的。胡乱扑腾。
    Reol
        22
    Reol  
       2020-01-18 16:25:51 +08:00
    @shintendo 感谢大佬,吃瓜过程发现原来自己理解的也不深刻。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2707 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:06 · PVG 17:06 · LAX 01:06 · JFK 04:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.