npm package: @justfn/callback
Description: callback killer 
Author: fsl
Latest version: 1.8.1
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# CallBack

#### 介绍
通常 一般的回调已被 promise 解决掉, 但仍有一部分回调, 无法拆出
考虑情况如下:
```js
document.addEventListener("click",(evt)=>{
  // 这里的回调函数, 无法使用 promise 来拆出 
  // 因为可能调用若干次, 且调用时机 人为控制的 
})


``` 
该库就是解决这种回调问题, 将回调拆出分层, 便于维护和开发, 效果如下 

```js
  callback(document, 'addEventListener', ['click'])
  .back((ctx, evt)=>{
    // 将点击的回调函数提出到这里
    
    // ctx.call(arg) // 来控制后续的回调调用及传参, 便于将逻辑分层及更好的维护性  
  })
  .back((ctx, arg)=>{
    // 该回调, 由前面的 ctx.call 方法来控制是否执行 
  })
```


#### 安装教程
$ npm i @justfn/callback 

#### 使用说明
```js
Example: 

// 引入 
import callback from "@justfn/callback";
// nodejs 中
const callback = require("@justfn/callback").default;

// 使用 
// 改造 let result = document.addEventListener("click", (evt)=>{ })

let dosomething = (cb)=>{
  setTimeout(()=>{
    cb(' hello cb')
  },1000)
}
let { result } = callback(document, 'addEventListener', ['click'])
.back((ctx, evt)=>{
  ctx.call(evt)
  
  if (Math.random()>0.5) {
    ctx.call(ctx.type('002'), evt)
  }
  else {
    ctx.call(ctx.type('001'), evt)
  }
})
.back((ctx, evt)=>{
  console.log(' 每次点击都会执行 ', evt);
  
  ['a','b','c'].forEach((itm,idx)=>{
    ctx.call(ctx.type('mutil'), itm, idx)
  })
})
.back('mutil', (ctx, itm, idx)=>{
  console.log('每次点击会执行多次', itm, idx);
})
.back('001', (ctx, evt)=>{
  console.log(' - 随机数小于等于0.5 ');
})
.back('002', (ctx, evt)=>{
  console.log(' = 随机数大于0.5 ');
  
  ctx.call( callback(null, dosomething) )
})
.back((ctx, arg)=>{
  console.log('这里的逻辑是走的 dosomething 的回调的');
  console.log( arg );
  
  ctx.call( new Promise((resolve, reject)=>{
    setTimeout(()=>{
      resolve('hello promise')
    }, 2000)
  }))
})
.back((ctx, val)=>{
  console.log(' 前面的promise resolved 后执行');
  console.log( val );
})

// result 是 document.addEventListener("click",function(evt){ }) 的返回值, 
// 有些场景可能会用到, 比如在 nodejs 中, 改造 createServer 时 
console.log( result ); 


```

```js
// 创建链的开端  

callback.call(111, 222) 
.back((ctx, ...args)=>{
  console.log( ...args );
  
})
```

```js
// 同步回调方法的改造 

const traversal_deep_recur = (node, cb)=>{
  if (!node) { return ; }
  
  cb && cb(node);
  let children = node[ 'children' ]
  if (!children) { return ; }
  
  children.forEach(itm=>traversal_deep_recur(itm,cb));
}

let treeNode = {
  name: 1,
  children: [
    {
      name: 11,
      children: [
        {
          name: 111,
        },
        {
          name: 112,
        },
      ],
    },
    {
      name: 12,
    },
  ],
}

let cbHandle = callback.sync(null, traversal_deep_recur, [ treeNode ])
.back((ctx, nd)=>{
  console.log( nd );
})
cbHandle.exec();

```

```js

// 每秒依次遍历数组 

let list = [
  'a1',
  'b2',
  'c3',
  'd4',
]

let handle = callback.call(0)
.back((ctx, idx)=>{
  if (idx>=list.length) {
    ctx.call('finished')
    return ;
  }
  
  console.log( idx, list[idx] );
  setTimeout(()=>{
    ctx.self(++idx)
  },1000)
})
.back((ctx, flg)=>{
  console.log( flg );
})


```

```js
// 来回振荡 3 次后结束 

let counter = 0;

callback.call(0)
.back((ctx, num1)=>{
  counter++;
  if (counter>=4) {
    console.log(' finished ');
    return ;
  }
  
  console.log('-', num1);
  setTimeout(()=>{
    ctx.call( num1+1 )
  },1000)
})
.back((ctx, num2)=>{
  console.log('+', num2);
  setTimeout(()=>{
    ctx.prev(num2-1)
  },1000)
})

```


```js
callback.call.sync('aa')
.back((ctx, val)=>{
  console.log( val );
})
.exec() // 
```


```js
// 添加防抖功能 
// debounce(
//   500,   // 防抖时间设置 
//   false  // 执行时是否携带之前未执行的参数 
// )

import { debounce } from "@justfn/callback";

let list = [
  'a',
  'b',
  'c',
  'd',
]
callback.sync( list, 'forEach')
.back((ctx, itm, idx, list)=>{
  console.log( itm, idx, list);
  ctx.call(itm, '-')
})
.back((ctx, itm, val, prevArgs)=>{
  console.log(itm, val, prevArgs );
}, debounce(2000, true) )
.exec();

```

```js
// 添加节流功能 
// throttle(
//   // 节流时间设置 
//   500, 
//   // 节流类型，
//   // 'head'  - 立即执行, 省略最后一次; 
//   // 'tail'  - 延迟执行, 包括最后一次 
//   // 'double'- 立即执行, 包括最后一次,默认值 
//   'double',  
//   // 执行时是否携带之前未执行的参数 
//   false 
// )
import { throttle } from "@justfn/callback";

let list = Array(20).fill('');

callback.call.sync( 0 )
.back((ctx, idx)=>{
  if (idx>=list.length) {
    return ;
  }
  
  setTimeout(()=>{
    console.log('-', idx, Date.now() );
    idx = idx+1;
    ctx.self(idx);
    ctx.call(idx);
  },100)
})
.back((ctx, idx, prevArgs)=>{
  console.log('=', idx, Date.now(), JSON.stringify(prevArgs) );
}, throttle(100*5, 'double', true) )
.exec();

```