什么时候需要异步钩子
异步钩子是在同步钩子概念的基础上做了进一步提升。在Javascript中,钩子内自行的操作很多时候是异步有延时的,此时,上一步的钩子还没执行完,下一步就已经开始了。这时需要使用异步钩子来按优先级依次执行添加时的钩子。
这要求在预埋钩子时就考虑到是使用同步钩子还是异步钩子
::: tip 约定
为了和同步钩子进行明确区分,在定义钩子名称时,应在异步钩子名前加入 async:
字样
:::
异步动作钩子
do_async_action
do_async_action(钩子名称:String, 参数1, 参数2...)
预埋钩子,执行add_action
的动作钩子,并提供动作的额外参数。
add_action
add_action(钩子名称:String, 回调函数:Function, 优先级:Number)
添加动作钩子,当代码运行到do_async_action
时,联动同名的操作。联动的回调参数接收do_action
传递的参数。
- 异步执行完后,必须用
next()
控制执行下一钩子
- 默认优先级:10
- 逻辑上完全相同(===)的同一个钩子,只会添加一次
与同步钩子区别
- 预埋钩子函数名从
do_action
变为 do_async_action
- 添加动作钩子函数名不变,但回调函数参数增加了1个
next
方法用于控制异步进程。且异步操作结束后,必须调用next
方法来执行下一个钩子。
例:
//==========添加可用钩子============
add_action("async:sample_hook",(next, arg1, arg2)=>{
// 这将在第二步执行
console.log(`第二步:${arg2}`)
next()
}, 10)
add_action("async:sample_hook",(next, arg1, arg2)=>{
// 这将在第一步执行,哪怕延迟了1秒,第二步也不会提前执行
setTimeout(()=>{
console.log(`第一步:${arg1}`)
next()
},1000)
}, 3)
add_action("async:sample_hook",(next, arg1, arg2)=>{
// 这将在第三步执行
setTimeout(()=>{
console.log(`第三步:${arg1}-${arg2}`)
next()
},500)
}, 11)
//==========正常的代码工作流============
do_async_action("async:sample_hook", "参数1", "参数2")
.then(()=>{
console.log("示例异步钩子全部执行完毕")
})
异步过滤器钩子
apply_async_filters
apply_async_filters(钩子名称:String, 被过滤的参数, 额外参数1, 额外参数2...)
.then( 过滤结果 => {
...
})
预埋钩子,执行add_filter
的过滤器钩子,并提供过滤器的额外参数。
add_filter
add_filter(钩子名称:String, 回调函数:Function, 优先级:Number)
添加钩子过滤器,当代码运行到apply_async_filters
时,运行回调函数,在函数中并返回过滤后的参数。
- 必须用
next(过滤结果)
返回参数,原则上返回的过滤后的参数应该与被过滤的参数类型、结构相同
- 默认优先级:10
- 逻辑上完全相同(===)的同一个钩子,只会添加一次
与同步钩子区别
- 预埋钩子函数名从
apply_filters
变为 apply_async_filters
- 添加过滤器钩子函数名不变,但回调函数参数增加了1个
next
方法用于控制异步进程。且异步操作结束后,必须调用next(过滤结果)
方法来执行下一个钩子。
例:
//==========添加可用钩子============
add_filter("async:sample_filter_hook",(next, tobe_filtered, arg1, arg2)=>{
// 这将在第二步执行
console.log(`第二步:${tobe_filtered}`)
tobe_filtered = tobe_filtered + arg2;
next(tobe_filtered)
}, 10)
add_filter("async:sample_filter_hook",(next, tobe_filtered, arg1, arg2)=>{
// 这将在第一步执行,哪怕延迟了1秒,第二步也不会提前执行
setTimeout(()=>{
console.log(`第一步:${tobe_filtered}`)
tobe_filtered = tobe_filtered + arg1;
next(tobe_filtered)
},1000)
}, 3)
add_filter("async:sample_filter_hook",(next, tobe_filtered, arg1, arg2)=>{
// 这将在第三步执行
setTimeout(()=>{
console.log(`第三步:${tobe_filtered}`)
tobe_filtered = tobe_filtered + 'END';
next(tobe_filtered)
},500)
}, 11)
//==========正常的代码工作流============
apply_async_filters("async:sample_filter_hook", "被过滤", "参数1", "参数2")
.then(val=>{
console.log("示例异步钩子全部执行完毕,过滤结果:", val)
})