# 异步函数队列

## 基本使用

``````var Sequence = require('func-sequence');

aSeq = new Sequence();

aSeq.push(function() {
setTimeout(function() {
console.log(1);
aSeq.next();
}, 400);
}).push(function() {
setTimeout(function() {
console.log(2);
aSeq.next();
}, 100);
}).next();
``````

``````> 1
> 2
``````

``````var Sequence = require('func-sequence');

function done() {
console.log('done');
}

function exit() {
console.log('exit');
}

aSeq = new Sequence(done, exit);

aSeq.push(function() {
setTimeout(function() {
console.log(1);
aSeq.done(); // aSeq.exit();
}, 400);
}).push(function() {
setTimeout(function() {
console.log(2);
aSeq.next();
}, 100);
}).next();
``````

``````> 1
> done
``````

``````var Sequence = require('func-sequence');

function done() {
console.log('done');
}

function exit() {
console.log('exit');
}

aSeq = new Sequence(done, exit);

aSeq.push(function() {
setTimeout(function() {
console.log(1);
aSeq.next();
}, 400);
}).push(function() {
setTimeout(function() {
console.log(2);
aSeq.next();
}, 100);
}).push(aSeq.done).next();
``````

``````> 1
> 2
> done
``````

## 传递数据

sequence对象有个data属性，可以保存需要用到的数据，并在被执行的函数中使用。传递数据的方式有如下几种：

• aSeq.push(func, data)
• aSeq.next(data)
• aSeq.nextElse(data)
• aSeq.done(data)
• aSeq.exit(data)

``````aSeq.push(function(data) {
console.log(data);
this.next();
});
``````

## 条件执行

``````var Sequence = require('func-sequence');

function done() {
console.log('done');
}

function exit() {
console.log('exit');
}

aSeq = new Sequence(done, exit);

aSeq.push(function(data) {
if (data.age > 18) {
this.next();
} else {
this.nextElse();
}
}).push(
function() {
console.log('so sexy!');
this.done();
},
function() {
this.exit();
}
)
.next({age : 28});
``````

``````> so sexy!
> done
``````

``````aSeq.push({
func : function() {
console.log('so sexy!');
this.done();
},
funcElse : function() {
this.exit();
},
condition : function(data) {
return data.age > 18;
}
});
``````

## 队列嵌套

``````var Sequence = require('func-sequence');

function done() {
console.log('done');
}

aSeq = new Sequence(done);

aSeq.push(function() {
var aSeq = this;
setTimeout(function() {
console.log(1);
aSeq.next();
}, 400);
}).push(function() {
var aSeq = this
;

function subDone() {
aSeq.next();
}

var subSeq = new Sequence(subDone);

subSeq.push(function() {
var subSeq = this
;

setTimeout(function() {
console.log('1-1');
subSeq.next();
}, 300);
}).push(function() {
var subSeq = this
;

setTimeout(function() {
console.log('1-2');
subSeq.next();
}, 200);
}).push(subSeq.done).next();

}).push(function() {
var aSeq = this;
setTimeout(function() {
console.log(2);
aSeq.next();
}, 100);
}).push(aSeq.done).next();
``````

``````> 1
> 1-1
> 1-2
> 2
> done
``````

## 一些技巧和注意

• next, done, exit都可以作为被执行函数push到队列中。
• 条件函数不能产生无限分支。
• 可以定义一些公用的异步调用，但在各种情况下，执行的顺序不同。

## 完整API参考

### Sequence([done[, exit]])

• @param {function=} done
• @param {function=} exit

### push(func)

• @param {function} func

### push(func, funcElse)

• @param {function} func
• @param {function} funcElse

### push(func, data)

• @param {function} func
• @param {object} data

### push(func, funcElse, data)

• @param {function} func
• @param {function} funcElse
• @param {object} data

### push(opt)

• @param {object} opt
• @key {function} func
• @key {function} funcElse
• @key {object} data
• @key {function|*} condition

### next([data])

• @param {object=} data

### nextElse([data])

• @param {object=} data

### done([data])

• @param {object=} data

### exit([data])

• @param {object=} data