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

2015-01-27 12:47:21 +08:00
 flowforever

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());
    }
})
2135 次点击
所在节点    Node.js
1 条回复
rekey
2015-01-27 15:20:19 +08:00
感觉 Promise 更清晰。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/165812

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX