js中常见的事件触发模式有订阅发布者模式,代码简洁,使用方便,但是这种模式并不能自动完成(除非把value作为常量或者变量存储),相对的Signal信号模式不需要创建常量来存储字符串值,轻松控制事件广播和订户,接下来是对该模式的一些总结。
使用:
var Signal = require('signals');
var mySignal = new Signal();
mySignal实例
1,属性
mySignal.active = false/true; //该信号监听调度是否停止,默认true可用
mySignal.memorize = false/true; //该信号是否记录之前的调度参数并且自动执行,默认为false不记录
mySignal.VERSION = ''; //记录当前信号的版本
2,方法:
add();添加监听器
//add(listener, listenerContext, priority);
//listener 属于function类型,是信号操作函数
//listenerContext 属于object类型,是监听器的执行上下文环境,可选
//priority 属于Number类型,是该监听器的优先级,高优先级的先执行,默认为0,可选
//返回值是 SignalBinding 类型
mySignal.add(listener, listenerContext, priority);
addOnce();添加一次性监听器,运行完一次即可自动remove
//add(listener, listenerContext, priority);
//listener 属于function类型,是信号操作函数
//listenerContext 属于object类型,是监听器的执行上下文环境,可选
//priority 属于Number类型,是该监听器的优先级,高优先级的先执行,默认为0,可选
//返回值是 SignalBinding 类型
mySignal.addOnce(listener, listenerContext, priority);
dispatch();调度/广播信号到所有监听器,加入队列,即让监听器运行
//dispatch(params),paras可选
mySignal.dispatch();
dispose();删除所有相关的信号对象和绑定,无返回值
mySignal.dispose();
forget();清除记忆的arguments,无返回值
mySignal.forget();
getNumListeners();返回该信号绑定的监听器的个数
mySignal.getNumListeners();
halt();停止分发事件,blocking the dispatch to next listeners on the queue.
mySignal.halt();
has();检查该信号是否与特定监听器绑定
//listener ; 监听器的执行函数
//context ;执行的上下文环境,可选
// 返回值为true 或者 false
mySignal.has(listener, context);
remove();删除监听器
//listener ; 监听器的执行函数
//context ;执行的上下文环境,可选
//返回监听器的执行函数handler
mySignal.remove(listener, context);
removeAll();删除该信号的所有监听器
mySignal.removeAll();
toString();返回当前的object的
Signal和redux-saga结合使用
1,首先在组件中加入监听事件
import signals from 'signals';
const Signal = signals.Signal;
const signSignal = new Signal();
export default signSignal;
部分代码:
componentWillMount() {
Signal.add(this.onListenerSignal);
}
componentWillUnmount() {
Signal.remove(this.onListenerSignal);
}
onListenerSignal = (key, param = {}) => {
const me = this;
switch (key) {
case TASK_DETAIL_ACTIONS.TASK_EXECUTE_FETCH_DETAIL:
me.doAction(key, param);
break;
case TASK_DETAIL_ACTIONS.TASK_EXECUTE_RESULT_BACK: {
const { memberMap, totalCount = 0, pageNum } = (param.data || {}).pageMemberProfile || {};
this.listViewComponentInstance.updateComponentLoadingStatus({
listMap: memberMap || {},
totalCount,
pageNum,
});
break;
}
case TASK_DETAIL_ACTIONS.TASK_LIST_LOADING:
if (param.loading) {
DDModule.onShowPreloader({});
} else {
DDModule.onHidePreloader({});
}
break;
case TASK_DETAIL_ACTIONS.TASK_GLOBAL_TOAST:
DGToast[param.type || 'info'](param.info);
break;
default: break;
}
}
2,在单个saga中触发,调用dispatch
export function* fetchTaskDetail({ data }) {
Signal.dispatch(TASK_DETAIL_ACTIONS.TASK_DETAIL_LOADING, {
loading: true,
});
const result = yield call(_request, ApiMaps.dg_task_detail, { ...data });
Signal.dispatch(TASK_DETAIL_ACTIONS.TASK_DETAIL_LOADING, {
loading: false,
});
const resultData = result.data || [];
if (result.success) {
yield put({
type: TASK_DETAIL_ACTIONS.TASK_RECURIT_RENDER_DETAIL,
data: { ...resultData, process: 'success' },
});
if (resultData.rights.hasTrackInfo) {
Signal.dispatch(TASK_DETAIL_ACTIONS.TASK_DETAIL_NOTICE_LIST_TYPE, {
type: 'track',
});
} else if (resultData.rights.hasExecuteInfo) {
Signal.dispatch(TASK_DETAIL_ACTIONS.TASK_DETAIL_NOTICE_LIST_TYPE, {
type: 'members',
});
}
} else {
yield put({
type: TASK_DETAIL_ACTIONS.TASK_RECURIT_RENDER_DETAIL,
data: { process: 'error', code: result.code, message: result.message },
});
Signal.dispatch(TASK_DETAIL_ACTIONS.TASK_GLOBAL_TOAST, {
type: 'info',
info: `${'拉取详情失败,请重试'} [${result.errCode || result.code || -1}]`,
});
}
}
参考:https://www.cnblogs.com/catherinezyr/p/7403485.html