CallBack
介绍
通常 一般的回调已被 promise 解决掉, 但仍有一部分回调, 无法拆出 考虑情况如下:
document.addEventListener("click",(evt)=>{
// 这里的回调函数, 无法使用 promise 来拆出
// 因为可能调用若干次, 且调用时机 人为控制的
})
该库就是解决这种回调问题, 将回调拆出分层, 便于维护和开发, 效果如下
callback(document, 'addEventListener', ['click'])
.back((ctx, evt)=>{
// 将点击的回调函数提出到这里
// ctx.call(arg) // 来控制后续的回调调用及传参, 便于将逻辑分层及更好的维护性
})
.back((ctx, arg)=>{
// 该回调, 由前面的 ctx.call 方法来控制是否执行
})
安装教程
$ npm i @justfn/callback
使用说明
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 );
// 创建链的开端
callback.call(111, 222)
.back((ctx, ...args)=>{
console.log( ...args );
})
// 同步回调方法的改造
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();
// 每秒依次遍历数组
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 );
})
// 来回振荡 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)
})
callback.call.sync('aa')
.back((ctx, val)=>{
console.log( val );
})
.exec() //
// 添加防抖功能
// 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();
// 添加节流功能
// 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();