V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LightingX
V2EX  ›  问与答

JavaScript 异步回调的同步问题

  •  
  •   LightingX · 2018-05-14 23:10:40 +08:00 · 2233 次点击
    这是一个创建于 2413 天前的主题,其中的信息可能已经有所发展或是发生改变。

    下列代码

    /* a */
    getXXX(function(){
        /* b */
    });
    /* c */
    

    如何让 c 在 b 后执行呢?

    12 条回复    2018-05-16 08:44:56 +08:00
    asdf123101
        1
    asdf123101  
       2018-05-14 23:14:42 +08:00 via Android
    把 c 直接放到 b 后面不好吗
    pheyer
        2
    pheyer  
       2018-05-14 23:16:55 +08:00 via iPhone
    Await/async 了解一下
    bucky
        3
    bucky  
       2018-05-14 23:24:10 +08:00
    把 c 传进去
    dablwow
        4
    dablwow  
       2018-05-14 23:42:18 +08:00
    c 不是自然在 b 后面吗?还是我理解错了?
    ![img.png]( https://s1.ax1x.com/2018/05/14/CrHtUA.png)
    LightingX
        5
    LightingX  
    OP
       2018-05-14 23:49:03 +08:00
    @dablwow 对,但是有一种情况是 b 执行得比较慢,然后 b 还没执行完的时候 c 就执行完了,你在 b 放一个 sleep 试试看
    zzNucker
        6
    zzNucker  
       2018-05-14 23:50:59 +08:00
    getXXX 写成 generator 或者 async
    LancerComet
        7
    LancerComet  
       2018-05-14 23:51:27 +08:00
    ```
    getName((error: Error, name: string) => {
    getAge((error: Error, age: number) => {
    const data = { name. age }
    sendData(data, (error: Error) => {
    // ...
    })
    })
    })

    function getName (callback: (error: Error, name: string) => void) {}
    function getAge (callback: (error: Error, age: number) => void) {}
    function sendData (data: { name: string, age: number }, callback: (error: Error) => void) {}
    ```

    ```
    (async () => {
    try {
    const name = await getName()
    const age = await getAge()
    await send({ name, age })
    } catch (error) {
    // ...
    }
    })()

    function getName (): Promise<string> {}
    function getAge (): Promise<number> {}
    function sendData (data: { name: string, age: number }): Promise<void> {}
    ```
    brickyang
        8
    brickyang  
       2018-05-15 00:24:17 +08:00 via iPhone
    一劳永逸的办法是用 Promise 把 getXXX 函数包一层,变成 getXXXAsync(),以后就能像同步一样使用它了,岂不美哉?
    Torpedo
        9
    Torpedo  
       2018-05-15 00:44:20 +08:00 via Android
    不是回调都是异步。
    getxxx 如果是同步函数就是 abc,异步操作才是 acb。所以这样不能保证顺序。
    使用 promise 可以保证你那部分代码是"异步的"
    至于把 getxxx 变成同步,除了 aync await 语法糖之外是不行的。毕竟 js 异步模型就是事件循环,阻塞 js 线程是明显出问题的
    shintendo
        10
    shintendo  
       2018-05-15 09:35:08 +08:00
    @LightingX

    你说的到底是 b 本身异步,还是 getXXX 异步?
    dablwow
        11
    dablwow  
       2018-05-15 13:50:50 +08:00
    @LightingX b 只要是同步代码,再慢也是先于 c 执行完毕的。如果是异步,c 不该写在 getXXX 外面
    tushankaka
        12
    tushankaka  
       2018-05-16 08:44:56 +08:00 via Android
    2 楼大哥说的对。promise, asyc/await 可以完美解决。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2871 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:16 · PVG 22:16 · LAX 06:16 · JFK 09:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.