Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chainjs

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chainjs - npm Package Compare versions

Comparing version 0.1.10 to 0.2.0

.travis.yml

121

chain.js

@@ -1,12 +0,5 @@

/*
* chainjs
* http://github.com/switer/chainjs
*
* Copyright (c) 2013 "switer" guankaishe
* Licensed under the MIT license.
* https://github.com/switer/chainjs/blob/master/LICENSE
*/
'use strict';
'use strict'
var utils = require('./lib/utils.js')
/*******************************

@@ -132,17 +125,17 @@ Chain

if (node.items) {
var proto = that.constructor.prototype
for (var index = 0; index < node.items.length; index++) {
var item = node.items[index]
var xArgs = args
var chainDummy = {
__id: node.id,
__index: index,
__callee: item,
__arguments: xArgs,
var ChainDummy = utils.create(function () {
this.__id = node.id
this.__index = index
this.__callee = item
this.__arguments = xArgs
this.state = that.state
this.props = that.props
}, proto)
var chainDummy = new ChainDummy()
chainDummy.next = utils.bind(proto.next, chainDummy)
state: that.state,
props: that.props
}
chainDummy.__proto__ = that.__proto__
chainDummy.next = utils.bind(chainDummy.__proto__.next, chainDummy)
xArgs.unshift(chainDummy)

@@ -298,82 +291,2 @@ item.apply(that.props._context, xArgs)

/**
* Util functions
**/
var utils = {
/**
* forEach
* I don't want to import underscore, it looks like so heavy if using in chain
*/
each: function(obj, iterator, context) {
if (!obj) return
else if (obj.forEach) obj.forEach(iterator)
else if (obj.length == +obj.length) {
for (var i = 0; i < obj.length; i++) iterator.call(context, obj[i], i)
} else {
for (var key in obj) iterator.call(context, obj[key], key)
}
},
some: function (arr, iterator) {
if (!arr) return
else if (arr.some) arr.forEach(iterator)
else {
for (var i = 0; i < arr.length; i++) {
if (iterator.call(null, arr[i], i)) break
}
}
},
/**
* Invoke handlers in batch process
*/
batch: function(context, handlers/*, params*/ ) {
var args = this.slice(arguments)
args.shift()
args.shift()
this.each(handlers, function(handler) {
if (handler) handler.apply(context, args)
})
},
/**
* binding this context
*/
bind: function(fn, ctx) {
// native bind is easey to cause maxium call stack
// if (fn.bind) return fn.bind(ctx)
return function () {
fn.apply(ctx, arguments)
}
},
/**
* Array.slice
*/
slice: function(array) {
// return Array.prototype.slice.call(array)
var i = array.length
var a = new Array(i)
while(i) {
i --
a[i] = array[i]
}
return a
},
/**
* Merge for extObj to obj
**/
merge: function(obj, extObj) {
this.each(extObj, function(value, key) {
if (extObj.hasOwnProperty(key)) obj[key] = value
})
return obj
},
type: function (obj) {
return /\[object ([a-zA-Z]+)\]/.exec(Object.prototype.toString.call(obj))[1].toLowerCase()
},
missing: function (param, paramName) {
if (!param) throw new Error('Missing param: ' + paramName)
},
want: function (obj, type) {
if (this.type(obj) != type) throw new Error('Want param ' + obj + ' type is a/an ' + type)
}
}
/**
* Link nodes data structure

@@ -426,8 +339,2 @@ **/

// AMD/CMD/node/bang
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) exports = module.exports = Bootstrap
exports.Chain = Bootstrap
} else this.Chain = Bootstrap
module.exports = Bootstrap

@@ -0,0 +0,0 @@ ## ChangeLog for: chainjs

{
"name": "chainjs",
"version": "0.1.10",
"version": "0.2.0",
"description": "Chainjs call each async function step by step, let async function callback fairily.",
"main": "chain.js",
"scripts": {
"test": "mocha test/test.js",
"cover": "jscoverage chain.js test/tmp/chain.js && npm run mocha-cover",
"mocha-cover": "mocha -r jscoverage --covout=html test/cover.js"
"test": "npm run coverall",
"mocha": "mocha test/test.js",
"coverall": "mocha --require blanket --reporter mocha-lcov-reporter ./test/test.js | ./node_modules/coveralls/bin/coveralls.js",
"cover-html": "mocha --require blanket --reporter html-cov ./test/test.js > coverage.html"
},

@@ -30,7 +31,18 @@ "repository": {

"devDependencies": {
"blanket": "^1.1.6",
"chai": "^1.10.0",
"colors": "^0.6.2",
"jscoverage": "^0.5.9",
"mocha": "^2.0.1"
"coveralls": "^2.11.2",
"gulp": "^3.9.0",
"gulp-header": "^1.7.1",
"gulp-watch": "^4.3.5",
"gulp-webpack": "^1.5.0",
"mocha": "^2.1.0",
"mocha-lcov-reporter": "0.0.1"
},
"config": {
"blanket": {
"pattern": "chain.js"
}
}
}

@@ -5,2 +5,7 @@ chainjs

[![Build Status](https://travis-ci.org/switer/chainjs.svg?branch=master)](https://travis-ci.org/switer/chainjs)
[![Coverage Status](https://coveralls.io/repos/switer/chainjs/badge.svg?branch=master)](https://coveralls.io/r/switer/chainjs?branch=master)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/switer/chainjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![npm version](https://badge.fury.io/js/chainjs.svg)](http://badge.fury.io/js/chainjs)
An asynchronous callback's flow controller, chaining async function callbacks. Async methods calling flow make easy. I use it in node.js server and webapp.

@@ -11,41 +16,85 @@

```bash
npm install chainjs
npm install chainjs --save
```
## Usage
:two_men_holding_hands: :two_men_holding_hands: :two_men_holding_hands:
__use in node:__
**Chainjs** can be used in [node.js](nodejs.org) or browser . Use in node as below:
```javascript
var Chain = require('chainjs')
Chain(function (chain) {
console.log('initialize');
chain.next('none');
Chain(function (chain, data) {
// initialize
console.log(data) // --> {name: 'Chainjs'}
chain.next();
})
.some(function (chain) {
chain.wait(300, 'then go to next in step 1')
}, function (chain) {
chain.wait(200, 'then go to next in step 2')
}, function (chain) {
chain.wait(100, 'then go to next in step 3')
.then(function (chain) {
chain.nextTo('branchStep')
})
.then(function (chain, data) {
console.log(data); // --> then go to next in step 3
chain.next('say hello');
var count = chain.data('count' || 0)
if (count > 2) {
chain.next('thenStep')
} else {
setTimeout(function () {
chain.data('count', count ++).retry()
})
}
})
.branch('branchStep', function (chain) {
chain.next('branchStep')
})
.then(function (chain, from) {
if (from == 'branchStep') {
// do something
}
chain.next()
})
.final(function (chain, data) {
console.log(data); // --> say hello
});
// do something when chain is ending
})
.start({name: 'Chainjs'})
```
:walking: :walking: :walking: :walking: :walking: :walking:
-----------------------------------------------------------
**Look at the diagram of above chain-flow:**
![diagram](http://switer.qiniudn.com/chainjs2.png)
![diagram](http://switer.qiniudn.com/chain-flow.png)
## API
Each step's handler has been passed the `chain` instance as the first argument
Each step's handler has been passed the `chain` instance as the first argument.
### Chain(func, func1, ..., funcN)
Instancing a chain, if arguments is not empty, it will be call .then() with arguments automatically.
If first argument is type of `Array`, that argument will be passed as arguments.
* Global API
- [Chain( *func, ..., funcN* )](#chainfunc--funcn)
- [then( *func, ..., funcN* )](#thenfunc--funcn)
- [some( *func, ..., funcN* )](#somefunc--funcn)
- [each( *func, ..., funcN* )](#eachfunc--funcn)
- [branch( *branchName, func* )](#branchbranchname-func)
- [context( *ctx* )](#contextctx)
- [thunk( *func* )](#thunkfunc)
- [start( *data, ..., dataN* )](#startdata--datan)
- [final( *finalHandler* )](#finalfinalhandler)
* Instance API
- [next( *data, ..., dataN* )](#nextdata--datan)
- [nextTo( *branchName, data, ..., dataN* )](#nexttobranchname-data--datan)
- [wait( *time, data, ..., dataN* )](#waittime-data--datan)
- [end( *data, ..., dataN* )](#enddata--datan)
- [data( *[key] [, value]* )](#datakey--value)
- [retry()](#retry)
- [destroy()](#destroy)
### Chain(func, ..., funcN)
:running: **[API Reference](#api)**
Create a Chain instance.
* if arguments is not empty, it will be call **.then()** with arguments automatically.
* else If first param is type of `Array`, then first param will be passed as arguments.
```javascript
Chain(func /*, func1, ..., funcN*/);
Chain(func /*, ..., funcN*/);
// or

@@ -55,3 +104,6 @@ Chain([func, func1, funcN])

### .then(func, func1, ..., funcN)
### .then(func, ..., funcN)
:running: **[API Reference](#api)**
Define a chain step, if a then step has multiple functions, it need each function call chain.next() to goto next step.

@@ -63,5 +115,5 @@ ```javascript

```javascript
Chain.then([func1, func2, ..., funcN])
Chain.then([func, ..., funcN])
// equal to
Chain.then(func1, func2, ..., funcN)
Chain.then(func, ..., funcN)
```

@@ -71,2 +123,5 @@

### .retry()
:running: **[API Reference](#api)**
Call current function once again (use for recursive).

@@ -84,3 +139,6 @@ ```javascript

### .some(func, func1, ..., funcN)
### .some(func, ..., funcN)
:running: **[API Reference](#api)**
Define a chain step, if a then step has multiple functions, it need any function of this step calling chain.next() only once to goto next step.

@@ -111,3 +169,6 @@ ```javascript

### .each(func, func1, ..., funcN)
### .each(func, ..., funcN)
:running: **[API Reference](#api)**
Define a chain step, call each handlers of this step in sequence. In this step, each function call chain.next() to call next function. In orders from left to right of arguments

@@ -124,3 +185,6 @@ ```javascript

### .start(data, data1, ..., dataN)
### .start(data, ..., dataN)
:running: **[API Reference](#api)**
Start running the chain, and could pass data to initial step.

@@ -134,2 +198,5 @@ ```javascript

### .destroy()
:running: **[API Reference](#api)**
Destroy the chain, mark the chain as ending and destroy local variable, but don't calling final funtions.

@@ -146,3 +213,6 @@

### .next(data, data1, ..., dataN)
### .next(data, ..., dataN)
:running: **[API Reference](#api)**
Go to next step

@@ -156,2 +226,5 @@ ```javascript

### .branch(branchName, func)
:running: **[API Reference](#api)**
Define a branch step, only using `chain.nextTo(branchName)` to goto branch step.

@@ -180,3 +253,6 @@ Call `chain.next()` from last step will skip next branch step.

### .nextTo(branchName, data, data1, ..., dataN)
### .nextTo(branchName, data, ..., dataN)
:running: **[API Reference](#api)**
Go to next branch.

@@ -203,3 +279,6 @@ ```javascript

### .wait(time, data, data1, ..., dataN)
### .wait(time, data, ..., dataN)
:running: **[API Reference](#api)**
Waiting some time then call next step.Just a shortcut of `setTimeout(function () {chain.next()}, time)`.

@@ -211,3 +290,6 @@ ```javascript

### .end(data, data1, ..., dataN)
### .end(data, ..., dataN)
:running: **[API Reference](#api)**
End up chain steps, mark the chain as ending, for cross steps data sharing

@@ -221,2 +303,5 @@ ```javascript

### .final(finalHandler)
:running: **[API Reference](#api)**
Define a final step, witch will be invoke after call chain.end() or all step of this chain is over.

@@ -238,3 +323,6 @@ ```javascript

### .data(savingData)
### .data([key] [, value])
:running: **[API Reference](#api)**
Saving data in current chain

@@ -257,2 +345,5 @@ ```javascript

### .thunk(func)
:running: **[API Reference](#api)**
Turn a regular node function into chainjs thunk.

@@ -276,2 +367,5 @@ ```javascript

### .context(ctx)
:running: **[API Reference](#api)**
Binding "this" to specified ctx for all functions of each step of current chain.

@@ -289,4 +383,3 @@ ```js

## Testing
Chainjs using [mocha](http://mochajs.org/) for BDD test, run below cli to run testing in nodejs
## Run Testing
```bash

@@ -296,54 +389,2 @@ npm test

## Example
See [using chainjs control business logic flow example](https://github.com/switer/chainjs-flow-control-demo)
```javascript
var Chain = require('chainjs');
var someStepCount = 0;
var parallelCount = 0;
Chain(function (chain) {
// save param
chain.data('chain:param', 'Chain initial step data');
chain.next({message: 'Next step'});
})
.some(function (chain, param) {
someStepCount ++;
chain.wait(2000, 'step is "some-1"');
}, function (chain, param) {
someStepCount ++;
chain.wait(1000, 'step is "some-2"');
})
.then(function (chain, msg) {
console.log(msg); // step is "some-2
// Step over when last step has one hander called
console.log(someStepCount); // 1
chain.next();
})
.then(function (chain) {
parallelCount ++;
chain.next();
}, function (chain) {
parallelCount ++;
chain.next();
}, function (chain) {
parallelCount ++;
chain.next();
})
.then(function (chain) {
// all handlers had been called in last step
console.log(parallelCount); // 3
chain.end();
})
.then(function (chain) {
//prev step had call chain.end(), so this step will be skiped
})
.final(function (chain) {
var param = chain.data('chain:param');
console.log(param); // "Chain initial step data"
})
.context(this)
.start(); // starting chain execute
```
## Change Log

@@ -350,0 +391,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc