usync v0.0.18
usync
The core of Usync is uniform serial execution, which can be run in browser or Node.js enviroment.
In addition, it supports task segmentation and task tree design. The root task state is added by default. Because Usync is very lightweight, core API is scarce, so Usync provides a set of hook and extension methods for life cycles that allow you to easily extend Usync.
app.use([task1,task2,task3 ... ]).start()中文请移步 README_zh_CN
Quick Start
Install
npm i usync -S
// or
yarn add usyncIf you want to test Usync in the browser, you can use the CDN as follows:
First usync app
var Usync = require('Usync')
// Create a task whose name is 'Work'
var app = Usync.app('Work')
// Define three subtasks
function task1(root, next) {
    // root: The root state that continues to pass down during the life cycle of 'Work' task
    // next: Call the next task
    setTimeout(() => next(), 200)
}
function task2(root, next) {
    setTimeout(() => next(), 300)
}
function task3(root, next) {
    setTimeout(() => next(), 200)
}
// Define task queues
app.use([task1,task2,task3])
// Running task
app.start()Features
- The type of subtask supports: Function/Usync/Promise/Async Function
- Provide Lifecycle Hook and Plugin mechanisms to facilitate extension
- Provide a root state (Root State) which is valid in the task life cycle by default
API
Usync.app([state])
- stateArray | Object | String
- return valueA Usync app instance
It's important to note that the state parameter is optional, and when the entire life cycle of the app needs to depend on a certain initialization state, we can inject it through state, for example:
let root = {
    // Initialize root status
} 
let app = Usync.app(root)Next, we can use the root state at each task in the app lifecycle:
app.use(function task1(root) {
    fx(root) // Perform some operations on the root state
});In addition, Usync initializes some values for the root state:
| attribute | description | 
|---|---|
| root.$current | Current task | 
| root.$prev | previous task | 
| root.$next | next task | 
Note: when the state is not set, the Usync constructor will generate a empty root state object by default
Usync.prototype.use(task)
- taskFunction | Usync | Promise | Async Function | Array
- return valuethis
This method is used to add subtasks to the Usync App. The use() method supports chain calls and also supports the introduction of an array.
app.use(task1).use(task2).use(task3)
// Equivalent to
app.use([task1, task2, task3])The execution order of the above examples is: task1 => task2 => task3。
The example of use() usage can be seen in the following example:
| Type | Example | 
|---|---|
| Function | Demo | 
| Promise | Demo | 
| Async/Await | Demo | 
| Usync | Demo | 
Note: The task needs to be a named function. Unlike the design philosophy
(taskName, taskHandler)of orchestrator and its gulp , Usync requires only onetaskHandler, and Usync will use the name oftaskHandleras the task's name.
You can run the examples provided by this project with git clone:
git clone https://github.com/toxichl/usync.git
npm i && npm run exampleNote:The above log effect is not built-in at Usync ,Because Usync core doesn't have any unique API of
NodeorBrowser. This log effect is implemented through a plug-in logger of Usync.
Life Cycle
The hook function of the life cycle provided by Usync is as follows:
| Hook | Parameter | Description | 
|---|---|---|
| init | (UsyncApp) | Before the end of an Usync appcreation | 
| beforeUse | (UsyncApp, task) | Before a task is going to be used in a Usync app | 
| appStart | (root) | Before a Usync appstarts running | 
| appEnd | (root) | Before a Usync appis finished running | 
| taskStart | (root) | Before a taskstarts running | 
| taskEnd | (root) | Before a taskis finished running | 
The properties available on a task are as follows:
| Attribute | Description | 
|---|---|
| task.name | task's name | 
| task.$parent | task's parent | 
About how to use these hooks, need the help of  Usync.extend() or Usync.prototype.extend, please continue to look down.。
Usync.extend(object)
- objectAn object consisting of one or more life cycle hook processing functions
- return valuenull
extend () accept an object as parameters, the object can contain multiple attributes, the attribute name for life cycle's name, the attribute value is a handler function, About the incoming parameter of handler function, please see last section. A simple extend() example is as follows:
Usync.extend({
    taskStart(root) {
        console.log(`Starting ${root.$current.name}`)
    },
    taskEnd(root) {
        console.log(`Finished ${root.$current.name}`)
    }
})In fact, this is the core part of implementing the plug-in logger. Is it very simple?
Usync.prototype.extend(object)
- objectAn object consisting of one or more life cycle hook processing functions
- return valuenull
Same to the Usync.extend(), the difference of them is that the Usync.extend() will influence all the UsyncApp, But Usync.prototype.extend() is only valid for the current UsyncApp. Please choose flexibly according to different scenes.
Usync.plugin(plugin)
- pluginObject | Function
- return valuenull
The plug-in's API design is inspired by Vue
Usync uses a plug-in API design that is consistent with Vue, and the Usync plug-in should have an open method, install. The first parameter of this method is the constructor of the Usync, and the second parameter is the optional option object.
You can refer to the implementation of logger  to learn how to combine a lifecycle hook and plugin API to write a plug-in for Usync.