1.0.2 • Published 10 years ago

fibers-domain v1.0.2

Weekly downloads
19
License
MIT
Repository
github
Last release
10 years ago

run in sequence, avoid callback-hell

Deprecated! use fibext instead.

fibers-domain extends node-fibers and node domain, to achieve code run in sequence and sync

Usage

var fd = require('fibers-domain');
fd.sync(function(){
  console.time('test');

  //sleep 1 second
  var domain = process.domain;
  setTimeout(function(){
    domain.resume();
  }, 1000);
  domain.wait();

  console.timeEnd('test')
});

Use With Express

require('fibers-domain');
app.use(function (req, resp, next) {
  var reqDomain = require('domain').create();
  reqDomain.on('error', function (err) {
    /*error handler*/
  });
  reqDomain.add(req);
  reqDomain.add(resp);
  reqDomain.run(next);
});
  1. 创建一个domain middleware, 如上
  2. 在后续请求的处理逻辑中, 可以直接使用domain.resume()domain.wait()来进行顺序执行(不需要再使用sync创建上下文)

Best Practice

因为web应用中, 基本上大部分的逻辑都是在处理请求, 所以可以认为大部分的逻辑都是在一个请求逻辑调用链中. 只要入口处使用fibers封装, 且所有的被调用者都按照fibers方式实现顺序执行, 那么整个调用链也可以认为是同步执行下去的. 具体操作方法

  1. 在express的中间件或http请求监听中, 注入domain. 如上所示;
  2. 在所有可能处于请求调用链上的方法中, 凡是有异步操作的内容, 均使用fibers-domain来将异步执行转化为顺序执行
  3. 这样, 基本上所有的方法都不需要传入callback来执行, 因为方法已经同步化了
require('fibers-domain');
app.use(/*domain middleware*/);
app.use('/query', function(req, resp, next){
  processRequest(req, resp);
});

function processRequest(req, resp){
  try{
    var r = queryDb();
    resp.json(r).end();
  }catch(e){
    resp.send(e.message);
  }
}

function queryDb(){
  var rows = null;
  var domain = process.domain, error = null;
  db.query(sql, function(err, _rows){
    error = err;
    rows = _rows;
    domain.resume();
  });
  domain.wait();
  if(error) throw error;
  return rows;
}

Run with both async/sync callback

In node-fibers, if you run fiber.run in a sync callback(which means that you call fiber.run before fiber.yield), you will get a thrown error. But in fibers-domain, you can call domain.resume() in a sync callback without any throw.

  function callbackSync(cb){
    /*do something*/
    cb();
  }

  fd.sync(function(){
    console.time('test');

    //sleep 1 second
    var domain = process.domain;
    callbackSync(function(){
      domain.resume();
    });
    domain.wait();

    console.timeEnd('test');
  });

So, no matter when you change the callbackSync method with an async cb or sync cb, the caller does not need to change the code.

License :

Licensed under MIT

Copyright (c) 2015 kiliwalk

1.0.2

10 years ago

1.0.1

10 years ago

1.0.0

10 years ago

0.3.0

10 years ago

0.2.0

10 years ago

0.1.6

10 years ago

0.1.5

10 years ago

0.1.4

10 years ago

0.1.3

10 years ago

0.1.2

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago