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

请问 javascript promise 的异步方法,到底怎么同步执行?

  •  
  •   maomaomao001 · 2016-11-14 22:45:59 +08:00 · 11956 次点击
    这是一个创建于 2968 天前的主题,其中的信息可能已经有所发展或是发生改变。
    console.log('开始');
    
    
    var zz =  sequelize.query("show tables",{ type: sequelize.QueryTypes.SHOWTABLES}).then((results)=>{
        results.forEach((item)=>{
            var bb =sequelize;
    
            console.log(item);
        });
    });
    console.log('1111');
    

    现在的结果是
    开始
    111
    然后再是表格信息

    28 条回复    2016-11-26 23:59:34 +08:00
    maomaomao001
        1
    maomaomao001  
    OP
       2016-11-14 22:52:50 +08:00 via Android
    表的信息
    Herobs
        2
    Herobs  
       2016-11-14 22:55:56 +08:00 via Android
    为什么要同步呢,同步就是一直等,线程被阻塞了
    Herobs
        3
    Herobs  
       2016-11-14 22:57:03 +08:00 via Android
    你可以把把输出 1111 放到回调函数里面,或者使用 waterfall 这样的函数
    smallpath
        4
    smallpath  
       2016-11-14 23:02:19 +08:00
    sequelize 还可以用在前端?

    不过无所谓,去搭 babel ,你要的就是 async/await
    maomaomao001
        5
    maomaomao001  
    OP
       2016-11-14 23:05:10 +08:00 via Android
    @Herobs 问题不是把 1111 放到回调里面~~ 我希望它同步执行啊~~
    bdbai
        6
    bdbai  
       2016-11-14 23:09:04 +08:00 via Android
    Promise 就是解决异步问题的,根据 Nodejs 的特性,没法同步。
    运行到 var zz 这一行时, sequelize 跑去异步取数据了,这是一个异步操作。还没取到数据,接着往下执行输出 1111 。等数据取回来了,又回进 then 里处理 results 。

    你可以在 then 函数后面再跟一个.then ,这样处理完第一个 then 才会进第二个 then 。
    maomaomao001
        7
    maomaomao001  
    OP
       2016-11-14 23:14:49 +08:00
    ```

    hello = Action.create({
    handler:function(req:vRequest,reply){

    //我要在这里取一点数据 -----
    sequelize.query("show tables",{ type: sequelize.QueryTypes.SHOWTABLES}).then((results)=>{
    results.forEach((item)=>{
    console.log(item);
    });
    });

    //可是还没取出来,它就往下执行,都已经吧 request 处理完了,返回了啊~~

    req.ex.attr['文章'] ={
    标题:'文章标题',
    作者:'maomaomao',
    内容:'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    };

    req.ex.template.file = 'index.ejs';

    }
    });

    ```

    真的不能同步吗?
    如果不能的话, nodejs 有没有 同步的 执行 sql 的 框架啊?
    maomaomao001
        8
    maomaomao001  
    OP
       2016-11-14 23:16:49 +08:00
    该是说,我像的不对吗??? 如果你们写 web 程序的话,这样的问题怎么处理?
    bdbai
        9
    bdbai  
       2016-11-14 23:19:26 +08:00 via Android
    @maomaomao001 你没理解“异步”吧,即便函数返回了,回调还可以“倒回去”执行的。
    按照 Promise 的做法,你在 then 函数后面再跟个 then 就能按顺序进行了。

    如果真用同步的,那查询一次整个线程就卡住了,完全没有发挥出 Nodejs 异步的优势。
    zhouquanbest
        10
    zhouquanbest  
       2016-11-14 23:20:51 +08:00
    await
    yield
    maomaomao001
        11
    maomaomao001  
    OP
       2016-11-14 23:25:08 +08:00 via Android
    @bdbai 我知道异步是什么意思。
    关键,我使用的框架都已经把数据返回给客户端了,我是的数据库还没异步查询完。。。数据到不了客户端,这怎么解决?
    murmur
        12
    murmur  
       2016-11-14 23:27:53 +08:00
    @maomaomao001 轮询后台啊 报表不都是这样么 定期在大半夜生成 等第二天上班的时候去看
    bdbai
        13
    bdbai  
       2016-11-14 23:29:19 +08:00 via Android
    @maomaomao001 你用的啥框架?主流 web 框架都没有这个问题啊...
    maomaomao001
        14
    maomaomao001  
    OP
       2016-11-14 23:32:01 +08:00 via Android
    @bdbai express , 我是感觉 这个查询不同步完全不可以,
    就像 nodejs 自己的同步读写文件那样。。。异步固然很好,但是同步影响逻辑啊
    bdbai
        15
    bdbai  
       2016-11-14 23:40:22 +08:00 via Android   ❤️ 1
    @maomaomao001 你这不像 express 啊,贴一下完整代码吧。

    我写的一个小例子:
    https://github.com/bdbai/nthskeys-node/blob/master/router/apiRouter.js

    用到 Nodejs 你就得接受异步的用法,不能因为理解不了就选择逃避...
    maomaomao001
        16
    maomaomao001  
    OP
       2016-11-14 23:58:45 +08:00 via Android
    @bdbai 天呐。。。 我怎么觉得这 promise 好反人类啊。。。
    bdbai
        17
    bdbai  
       2016-11-15 00:03:41 +08:00 via Android
    @maomaomao001 并不反人类,一路 then 下去就可以了。搞明白 Promise 以后可以试试 async/await 。
    FrankFang128
        18
    FrankFang128  
       2016-11-15 03:07:03 +08:00 via Android
    你中了同步的读
    des
        19
    des  
       2016-11-15 08:59:28 +08:00 via Android
    @maomaomao001 非要解释的简单的话,
    你就想象,你吃了早饭才回去上班,可是你又不能盯着别人什么事都不做吧?(假设你很忙)
    早点师傅会做好了通知你(通过回调或者类似的东西)
    你吃了早点就可以高高兴兴的去上班了(返回给用户)

    同步就像是你坐公交上班,每个路口都可能要等红灯
    maomaomao001
        20
    maomaomao001  
    OP
       2016-11-15 09:06:26 +08:00 via Android
    @bdbai 我突然发现一个更严重的问题。 在处理一个请求的时候,比如空循环耗时操作 10 秒的话,第二个浏览器访问的时候居然只能等到第一个浏览器结束后才开始?? nodejs 高并发体现在哪里啊?
    des
        21
    des  
       2016-11-15 09:07:27 +08:00 via Android
    @maomaomao001 你可以把 promise 想象成回调的统一封装,这样就比较容易理解
    逻辑上就是你必须把返回用户的逻辑写在回调里面,或者用 promise
    des
        22
    des  
       2016-11-15 09:12:48 +08:00 via Android
    @maomaomao001 看来你还是没明白异步的意义
    异步就是为了完全的利用 CPU
    你这样空循环到了同步上面照样把 CPU 吃的死死的,就算你能同时处理 3 个用户,那么好, 9 个用户呢?

    另外 nodejs 确实不适合用于消耗 CPU 的地方
    Herobs
        23
    Herobs  
       2016-11-15 09:16:40 +08:00 via Android
    @des 现实是程序很多时候都在 IO , CPU 消耗很大的程序用什么模型都一样。参见 nginx 吊打 apache 。
    maomaomao001
        24
    maomaomao001  
    OP
       2016-11-15 09:23:35 +08:00 via Android
    @des 可是我以为每个请求它都是单独处理,不互相印象呢。。。
    xjp
        25
    xjp  
       2016-11-15 10:01:44 +08:00 via iPhone
    promise 里 then 中的函数要等到当前所有的执行队列执行完成之后才会执行 你可以理解为给这个函数是在 setTimeout(...,0)里面执行的 是异步的 这个是 promiseA/A+规范中定义的
    bdbai
        26
    bdbai  
       2016-11-15 19:08:32 +08:00 via Android
    @maomaomao001 Nodejs 是单线程异步模型, CPU 阻塞当然得等。再说别的也这样,这锅 node 不背。
    peneazy
        27
    peneazy  
       2016-11-26 23:45:46 +08:00 via Android
    js 是单线程的,代码的执行都是以队列的形式。 then 方法里的代码也是要进队列里排队的,而不是只要 resolve 了就能立马执行。
    maomaomao001
        28
    maomaomao001  
    OP
       2016-11-26 23:59:34 +08:00 via Android
    嗯,解决了~~~以异步方法放进 async 函数里~~用的时候用 await
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1444 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:09 · PVG 01:09 · LAX 09:09 · JFK 12:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.