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

js 的回调如何给父级赋值?

  •  
  •   RickyC · 2021-03-09 17:02:02 +08:00 · 3572 次点击
    这是一个创建于 1384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    function verify(){
        var ret = false
        
        $.post('api.php',
        	{code: 222},
            
        	function(res){
        	   if(res.code === 200){
                
                    //这样赋值是无效的
                	ret = res.data.ret
                }
        	}
        })
    	return ret
      }
    

    众所周知 jQuery 已经弃用了 async 参数,所以怎么搞?

    42 条回复    2021-03-10 11:45:24 +08:00
    chenluo0429
        1
    chenluo0429  
       2021-03-09 17:04:17 +08:00 via Android   ❤️ 1
    赋值显然是有效的,只是你 return 时,ret 还没有被赋值
    foolnius
        2
    foolnius  
       2021-03-09 17:06:27 +08:00
    请求是异步操作,异步还没触发回调就直接返回了
    kaiki
        3
    kaiki  
       2021-03-09 17:08:44 +08:00
    ajax 是异步的,你应该把 return 写在赋值后
    你多加点 console.log 调试下就知道了
    ayase252
        4
    ayase252  
       2021-03-09 17:09:42 +08:00 via iPhone
    return promise
    外面 .then
    RickyC
        5
    RickyC  
    OP
       2021-03-09 17:10:07 +08:00
    @kaiki 赋值是在回调里的,
    回调里不能给父级 return 吧?
    RickyC
        6
    RickyC  
    OP
       2021-03-09 17:10:47 +08:00
    @chenluo0429 对呀,怎么解决
    toma77
        7
    toma77  
       2021-03-09 17:12:20 +08:00 via iPhone
    setTimeout 包一下 return
    sannyzeng
        8
    sannyzeng  
       2021-03-09 17:13:11 +08:00
    用 4 楼的方法,没问题啊
    wangxiaoaer
        9
    wangxiaoaer  
       2021-03-09 17:14:48 +08:00
    一句话,现在的 verify 是同步函数里面调用了异步方法,所以得不到内部异步的处理结果。

    解决办法是:verify 增加一个 callback 参数,内部的异步过程完成再触发这个 callback
    imdong
        10
    imdong  
       2021-03-09 17:15:05 +08:00
    想起来前几天群里聊到的面试题,类似的情况说不添加新的 fun 的情况下如何实现返回;

    答案:

    if 死循环等待

    很傻,但这样的构架只能这么搞,除非你能改变外面的调用方式

    比如回调,或者 Promise
    ytxbnahn
        11
    ytxbnahn  
       2021-03-09 17:15:20 +08:00
    async: false
    Jirajine
        12
    Jirajine  
       2021-03-09 17:15:39 +08:00 via Android
    你的请求是异步的,所以你的 verify()函数也得是异步的。
    可以用 async 、Promise,也可以用 callback 。
    ytxbnahn
        13
    ytxbnahn  
       2021-03-09 17:16:00 +08:00
    对不起 看错了
    justin2018
        14
    justin2018  
       2021-03-09 17:16:40 +08:00
    javascript - How do I return the response from an asynchronous call? - Stack Overflow
    https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call
    Vegetable
        15
    Vegetable  
       2021-03-09 17:17:21 +08:00
    问就是回调地狱啊
    sun2920989
        16
    sun2920989  
       2021-03-09 17:19:33 +08:00
    使用 async/await 的好时机.
    eason1874
        17
    eason1874  
       2021-03-09 17:20:48 +08:00
    赋值是有效的,但是 $.post 是异步的,没等响应 JS 就执行到下面的 return ret 了

    你可以你需要调用 verify() 结果的代码写成函数,在响应回调里调用。比如函数名 update_verify,update_verify(res.data.ret)
    chenluo0429
        18
    chenluo0429  
       2021-03-09 17:22:35 +08:00 via Android
    1. promise 包装一层
    2. verify 接受一个 callback 函数作为参数,让 callback 来接收 ret
    RickyC
        19
    RickyC  
    OP
       2021-03-09 17:31:10 +08:00
    @toma77 我想到的也是这个。不知道有什么优雅的方法吗
    eason1874
        20
    eason1874  
       2021-03-09 17:35:03 +08:00
    @RickyC #19 优雅的方法就是回调啊,callback,很多人都说了。没必要用定时器
    muzuiget
        21
    muzuiget  
       2021-03-09 17:47:53 +08:00
    楼上好几个人说了,要么 promise,要么 callback,楼主还是无视,基础知识不过关,没有异步的概念。
    Rhilip
        22
    Rhilip  
       2021-03-09 18:05:09 +08:00
    async/await 最适合了,反正 jQuery 的 ajax 也是支持 await 的。
    zhengwenk
        23
    zhengwenk  
       2021-03-09 18:08:45 +08:00   ❤️ 1
    既然用了异步就按异步的写法来啊,返回值又是同步的,这不是矛盾么。
    回旋标扔出去以后你手就空了。
    zhuweiyou
        24
    zhuweiyou  
       2021-03-09 18:15:16 +08:00   ❤️ 2
    function verify( callback ){

    $.post('api.php',
    {code: 222},

    function(res){
    if(res.code === 200){
    callback( res.data.ret )

    }
    }
    })
    }

    用的时候

    verify(ret => {
    console.log(ret)
    })
    wgbx
        25
    wgbx  
       2021-03-09 18:19:14 +08:00
    24 是标答啊,大家一直在说 promise 和 async,后面又会引出 babel,webpack,cli,node,无穷无尽了
    mmlmml1
        26
    mmlmml1  
       2021-03-09 18:25:48 +08:00
    jQuery 自带同步支持,真要同步的话可以直接 return $.post(...)
    mmlmml1
        27
    mmlmml1  
       2021-03-09 18:26:36 +08:00
    参数里面带上 async: false 即可
    Building
        28
    Building  
       2021-03-09 18:27:10 +08:00 via iPhone
    这种问题...有答的必要吗?
    zlu1123
        29
    zlu1123  
       2021-03-09 19:09:04 +08:00
    使用回调啊,在 success 里面判断 callBack && callBack(res)
    Ice7173
        30
    Ice7173  
       2021-03-09 19:22:17 +08:00
    在成功函数里做 callback,用 callback&&callback ( res ),或者 return 一个 promise,用.then()接参,这样就不会导致异步操作了,asnyc 其实也不好
    oott123
        31
    oott123  
       2021-03-09 20:19:42 +08:00 via Android
    @imdong 这个场景下,死循环等待是没有用的。

    单线程模型下,死循环会导致回调永远得不到执行。
    autoxbc
        32
    autoxbc  
       2021-03-09 21:16:59 +08:00
    @wgbx #25 时代变了,promise 和 async 已经是原生特性,和后面那些完全不同
    en20
        33
    en20  
       2021-03-09 23:14:09 +08:00   ❤️ 4
    @Building 大家都是从新手过来的,如果当初能有人帮助我真的会很感激.
    Shook
        34
    Shook  
       2021-03-09 23:39:22 +08:00
    1. async/await
    2. callback
    rencoo
        35
    rencoo  
       2021-03-09 23:54:18 +08:00
    $.post('api.php', {code: 222})
    .success((data) => {
    // 在这里赋值
    });
    meepo3927
        36
    meepo3927  
       2021-03-10 08:56:46 +08:00
    函数里直接 return $.post(...)

    然后外面直接 .then()

    习惯异步
    Reapper
        37
    Reapper  
       2021-03-10 09:03:27 +08:00
    不想用 async 同步到话,老办法只能 callback 一下啦,新方法就是 promise 啦!
    function verify(callback){
    $.post('','',function(){
    typeof callback === 'function' && callback()
    })
    }
    wednesdayco
        38
    wednesdayco  
       2021-03-10 10:34:16 +08:00
    这题这题是刚学 JavaScript 么……父级这个词用的也蛮灵性……但这种的也还是更推荐 Promise 封装
    no1xsyzy
        39
    no1xsyzy  
       2021-03-10 11:00:12 +08:00
    得理解 JavaScript 的纯异步思想
    一旦进入异步,你可以指望从现在开始 2000 年以后才会得到结果。
    PEAL
        40
    PEAL  
       2021-03-10 11:20:15 +08:00
    函数增加 callback 参数啊
    jorneyr
        41
    jorneyr  
       2021-03-10 11:42:26 +08:00
    回调函数或者 Promise 吧
    lemon6
        42
    lemon6  
       2021-03-10 11:45:24 +08:00   ❤️ 1
    参考下 24 楼的回答
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1384 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:50 · PVG 00:50 · LAX 08:50 · JFK 11:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.