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

使用 avril.queue 解决 node.js 异步流程控制

  •  
  •   flowforever · 2015-01-27 12:47:21 +08:00 · 2036 次点击
    这是一个创建于 3379 天前的主题,其中的信息可能已经有所发展或是发生改变。

    avril.queue avQ 甜到忧伤

    github: github.com/flowforever/avril.queue

    大家要觉得avQ还给力不妨给个start鼓励一下。

    install avril.queue

    npm install avril.queue
    

    目前avQ只支持node.js环境,以后有时间会再添加browser环境支持.
    avQ通过queue, $awaitData实现异步流程控制。
    $awaitData 可以作为结果返回给其他avQ使用,使用avQ不会打乱原有的程序逻辑结构。

    q.$await 方法默认返回回调的第一个参数作为$awaitData 的结果
    q.$$await 方法则默认返回第二个参数作为结果并将第一个参数作为error层层上抛

    /*
    assume that we have a file "the/path/of/file.txt"
    the file content is :
    1
    2
    3
    */
    

    func, $await , $each

    var avQ = require('avril.queue');
    var q = avQ();
    
    /* return $AwaitData object */
    var $fileContent = q.$await(fs.readFile, 'the/path/of/file.txt'
    , function(err, fileContent){
      this.error(err);
      return fileContent;
    });
    
    /* conver the $awaitData' result , return a new $AwaitData object */
    var $ids = $fileContent.conver(function($org){
      return $org.result().split('\n');
    }); 
    
    /*  return $AwaitData object which result is list of */
    var $users = q.$each(db.User.findById, $ids, function(err, user){
      this.error(err);
      return user;
    }); 
    
    q.func(function(){
      console.log( $fileContent.result() )
      console.log( $users.realResult() );
    });
    

    $$await & $$each

    var avQ = require('avril.queue');
    var q = avQ();
    
    /* return $AwaitData object */
    var $fileContent = q.$$await(fs.readFile, 'the/path/of/file.txt'); 
    
    /* conver the $awaitData' result , return a new $AwaitData object */
    var $ids = $fileContent.conver(function($org){
      return $org.result().split('\n');
    }); 
    
    /*  return $AwaitData object which result is list of */
    var $users = q.$$each(db.User.findById, $ids); 
    
    q.func(function(){
       console.log( $fileContent.result() )
       console.log( $users.realResult() );
    });
    

    use $await, $each, with context

    var avQ = require('avril.queue');
    var q = avQ();
    
    /* return $AwaitData object */
    var $fileContent = q.$await(fs, fs.readFile, 'the/path/of/file.txt'
    , function(err, fileContent){
      this.error(err);
      return fileContent;
    });
    
    /* conver the $awaitData' result , return a new $AwaitData object */
    var $ids = $fileContent.conver(function($org){
      return $org.result().split('\n');
    }); 
    
    /*  return $AwaitData object which result is list of */
    var $users = q.$each(db.User, db.User.findById, $ids, function(err, user){
        this.error(err);
    
        /* use this.$$await instead of q.$$await
        * use this.$$wait, the queue will wait the asynCall ready then go to next step
        * use q.$$wait only append current asynCall to the end of the queue, it's not what we want
        */
        user.blogs = this.$$await(db.Blogs, db.Blogs.findByUserId, user.id);
    
        return user;
    }); 
    
    q.func(function(){
       console.log( $fileContent.result() )
       console.log( $users.realResult() );
    });
    

    use q.$if($awaitData, trueFunc).$else(falseFunc)

    var avQ = require('avril.queue');
    var q = avQ();
    var filePath = 'the/path/of/file.txt';
    var $fileExisted = q.$await(fs.exists, filePath);
    var $fileContent;
    q.$if($fileExited, function(){
        /* use this.$$await instead of q.$$await
        * use this.$$wait, the queue will wait the asynCall ready then go to next step
        * use q.$$wait only append current asynCall to the end of the queue, it's not what we want
        */
        $fileContent = this.$$await(fs.readFile, filePath); 
    })
    q.func(function(){
        if($fileContent){
            console.log($fileContent.result());
        }
    });
    
    var otherPath = 'the/path/of/otherFile.txt';
    
    q.$if($fileContent, function(){
        $fileContent = this.$$await(fs.readFile, filePath);
    }).$elseIf(q.$await(fs.exits, otherPath), function() {
        $fileContent = this.$$await(fs.readFile, otherPath);
    });
    
    q.func(function(){
        if($fileContent){
            console.log($fileContent.result());
        }
    })
    
    rekey
        1
    rekey  
       2015-01-27 15:20:19 +08:00
    感觉 Promise 更清晰。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3226 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:09 · PVG 20:09 · LAX 05:09 · JFK 08:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.