V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wuhuaji
V2EX  ›  Node.js

Node.js 同时取多个数据并渲染问题

  •  
  •   wuhuaji · 2016-07-15 11:58:59 +08:00 · 4703 次点击
    这是一个创建于 3063 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小弟初学 node ,有个地方想不明白,想请教一下。

    例如我现在要取得 A 、 B 两个数据,并渲染到模板中

    传统的渲染模型大概是这样:

    var A = getDataA('param')
    var B = getDataB('param')
    
    // 这里,获取到了 A 、 B 两个数据,然后一并作为数据渲染到模板中:
    render('template',{
        'a':A,
        'b':B
    })
    

    但是因为 node 中的异步操作,一般都不直接返回结果,而是传入一个回调函数,处理获取的结果

    getDataA('param',funciton(A){
    	//这里获取到了 A ,并处理,此时可以去获取B
        
    	getDataB(param,function(B){
    		//获取到 B
    		//这里就访问不到 A 了,此时在这里渲染出去,就只能渲染 B,有没有什么办法 A/B 同时获取,并渲染模板
         render('template',{
         	'b':B
         })
    	})
    })
    

    请教有什么好的解决办法,或者是我又想不到的地方?

    16 条回复    2016-07-15 23:26:41 +08:00
    aivier
        1
    aivier  
       2016-07-15 12:14:19 +08:00 via Android   ❤️ 1
    这里应该是能访问到 A 的吧...
    Jeremial
        2
    Jeremial  
       2016-07-15 12:14:39 +08:00   ❤️ 1
    ```
    var a = yield getData('A');
    var b = yield getData('B');
    render('template', {
    'a': a,
    'b': b
    });
    ```


    ```
    var a = getData('A'); // get a promise
    var b = getData('B'); // get a promise

    Promise.all([a, b]).then(function(a, b){
    render('template', {
    a: a,
    b: b
    })
    });
    ```
    Jeremial
        3
    Jeremial  
       2016-07-15 12:16:01 +08:00   ❤️ 1
    上面 promise.all().then 得到的是一个 array, 不是 a, b 两个参数
    haozhang
        4
    haozhang  
       2016-07-15 12:16:29 +08:00 via iPhone   ❤️ 1
    在 getDataB 的回调函数里面是可以访问到 A 的
    wuhuaji
        5
    wuhuaji  
    OP
       2016-07-15 12:21:34 +08:00 via Android
    @haozhang 多谢指正,看来基础还是 不够牢固
    wuhuaji
        6
    wuhuaji  
    OP
       2016-07-15 12:23:21 +08:00 via Android
    @Jeremial 谢谢,回去看下 promise
    zhuangzhuang1988
        7
    zhuangzhuang1988  
       2016-07-15 12:31:57 +08:00   ❤️ 1
    sherlocktheplant
        8
    sherlocktheplant  
       2016-07-15 12:46:15 +08:00   ❤️ 1
    用 async 库的话比较简单

    async.parallel([
    function(callback) { getData('A', callback) },
    function(callback) { getData('B', callback) }
    ], function(err, results){
    var a = results[0];
    var b = results[1];
    render('template', {
    a: a,
    b: b
    });
    });

    不用库的话
    var a,b, aFetched, bFetched;

    getData('A', function(result){
    a = result;
    aFetched = true;
    checkResults();
    });

    getData('B', function(result){
    b = result;
    bFetched = true;
    checkResults();
    });

    function checkResults(){
    if(bFetched && bFetched) {
    render({
    a: a,
    b: b
    });
    }
    }
    Mirachael
        9
    Mirachael  
       2016-07-15 13:18:17 +08:00   ❤️ 1
    async +1
    wuhuaji
        10
    wuhuaji  
    OP
       2016-07-15 14:14:22 +08:00
    @Jeremial 感谢指点,解决了我的问题。

    其他朋友的指点也很好,回去好好总结一下!
    123s
        11
    123s  
       2016-07-15 16:11:26 +08:00   ❤️ 1
    generator 都说了,为什么不说 async/await
    welefen
        12
    welefen  
       2016-07-15 18:23:44 +08:00   ❤️ 1
    用 ThinkJS 这些问题框架自动给解决了
    wuhuaji
        13
    wuhuaji  
    OP
       2016-07-15 19:02:18 +08:00 via Android
    @123s 因为我还没来得及看相关的内容,今天才了解了 promise
    marvinwilliam
        14
    marvinwilliam  
       2016-07-15 21:02:49 +08:00
    可以试试 promise.all
    wuhuaji
        15
    wuhuaji  
    OP
       2016-07-15 21:48:47 +08:00 via Android
    @marvinwilliam 谢谢,正是用 promise.all 解决了这个问题
    klesh
        16
    klesh  
       2016-07-15 23:26:41 +08:00 via Android
    这个场景用 props 更好
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1216 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:18 · PVG 07:18 · LAX 15:18 · JFK 18:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.