maomaomao001
V2EX  ›  问与答

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

  •  
  •   maomaomao001 · Nov 14, 2016 · 12376 views
    This topic created in 3476 days ago, the information mentioned may be changed or developed.
    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 replies    2016-11-26 23:59:34 +08:00
    maomaomao001
        1
    maomaomao001  
    OP
       Nov 14, 2016 via Android
    表的信息
    Herobs
        2
    Herobs  
       Nov 14, 2016 via Android
    为什么要同步呢,同步就是一直等,线程被阻塞了
    Herobs
        3
    Herobs  
       Nov 14, 2016 via Android
    你可以把把输出 1111 放到回调函数里面,或者使用 waterfall 这样的函数
    smallpath
        4
    smallpath  
       Nov 14, 2016
    sequelize 还可以用在前端?

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

    你可以在 then 函数后面再跟一个.then ,这样处理完第一个 then 才会进第二个 then 。
    maomaomao001
        7
    maomaomao001  
    OP
       Nov 14, 2016
    ```

    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
       Nov 14, 2016
    该是说,我像的不对吗??? 如果你们写 web 程序的话,这样的问题怎么处理?
    bdbai
        9
    bdbai  
       Nov 14, 2016 via Android
    @maomaomao001 你没理解“异步”吧,即便函数返回了,回调还可以“倒回去”执行的。
    按照 Promise 的做法,你在 then 函数后面再跟个 then 就能按顺序进行了。

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

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

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

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

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