JavaScript 中回调函数封装

JavaScript 中回调函数封装

在JavaScript类中封装回调函数是一种常见的设计模式,可以帮助管理异步操作和事件处理。以下是几种在类中封装回调函数的方法:

1. 基本的回调函数封装

javascript 复制代码
class DataFetcher {
    constructor() {
        this.data = null;
    }

    fetchData(callback) {
        // 模拟异步数据获取
        setTimeout(() => {
            this.data = { id: 1, name: 'Example' };
            // 调用回调函数
            callback(this.data);
        }, 1000);
    }
}

// 使用示例
const fetcher = new DataFetcher();
fetcher.fetchData((data) => {
    console.log('数据已获取:', data);
});

2. 使用箭头函数保持上下文

javascript 复制代码
class EventHandler {
    constructor() {
        this.events = [];
    }

    // 使用箭头函数确保正确的this绑定
    addEvent = (event, callback) => {
        this.events.push({ event, callback });
    }

    triggerEvent(eventName) {
        const matchedEvents = this.events.filter(e => e.event === eventName);
        matchedEvents.forEach(e => e.callback());
    }
}

// 使用示例
const handler = new EventHandler();
handler.addEvent('login', () => {
    console.log('用户登录成功');
});
handler.triggerEvent('login');

3. Promise和回调函数结合

javascript 复制代码
class AsyncService {
    constructor() {
        this.status = 'idle';
    }

    // 使用Promise封装回调
    performTask(callback) {
        return new Promise((resolve, reject) => {
            this.status = 'processing';
            
            setTimeout(() => {
                try {
                    // 执行任务
                    const result = { success: true, message: '任务完成' };
                    
                    // 如果提供了回调函数,调用回调
                    if (callback) {
                        callback(null, result);
                    }
                    
                    // 解析Promise
                    resolve(result);
                    
                    this.status = 'completed';
                } catch (error) {
                    // 如果提供了回调函数,调用回调
                    if (callback) {
                        callback(error, null);
                    }
                    
                    // 拒绝Promise
                    reject(error);
                    
                    this.status = 'error';
                }
            }, 1000);
        });
    }
}

// 使用示例
const service = new AsyncService();

// 使用回调函数
service.performTask((error, result) => {
    if (error) {
        console.error('任务失败:', error);
    } else {
        console.log('任务结果:', result);
    }
});

// 使用Promise
service.performTask()
    .then(result => {
        console.log('任务成功:', result);
    })
    .catch(error => {
        console.error('任务失败:', error);
    });

4. 多回调和事件监听模式

javascript 复制代码
class EventEmitter {
    constructor() {
        this.listeners = {};
    }

    // 添加事件监听器
    on(event, callback) {
        if (!this.listeners[event]) {
            this.listeners[event] = [];
        }
        this.listeners[event].push(callback);
    }

    // 触发事件
    emit(event, ...args) {
        const eventListeners = this.listeners[event];
        
        if (eventListeners) {
            eventListeners.forEach(callback => {
                callback(...args);
            });
        }
    }

    // 移除特定事件的监听器
    off(event, callback) {
        const eventListeners = this.listeners[event];
        
        if (eventListeners) {
            this.listeners[event] = eventListeners.filter(
                listener => listener !== callback
            );
        }
    }
}

// 使用示例
const emitter = new EventEmitter();

// 添加多个监听器
const loginHandler1 = (user) => {
    console.log('登录处理1:', user);
};

const loginHandler2 = (user) => {
    console.log('登录处理2:', user);
};

emitter.on('login', loginHandler1);
emitter.on('login', loginHandler2);

// 触发事件
emitter.emit('login', { username: 'john_doe' });

// 移除特定监听器
emitter.off('login', loginHandler1);

这些示例展示了在JavaScript类中封装回调函数的不同方法:

  1. 简单的回调函数调用
  2. 使用箭头函数保持上下文
  3. 结合Promise和回调
  4. 事件发射器模式(类似Node.js的EventEmitter)

选择哪种方法取决于具体的使用场景。通常,现代JavaScript更倾向于使用Promise和async/await,但回调函数仍然在某些情况下很有用。

关键点:

  • 注意this的上下文
  • 提供灵活的调用方式
  • 考虑错误处理
  • 根据具体需求选择合适的模式
相关推荐
Rhys..16 小时前
ES6是什么
前端·javascript·es6
Jammingpro17 小时前
【Vue专题】前端JS基础Part1(含模版字符串、解构赋值、变量常量与对象)
前端·javascript·vue.js
quweiie1 天前
thinkphp8+layui多图上传,带删除\排序功能
前端·javascript·layui
闲蛋小超人笑嘻嘻1 天前
树形结构渲染 + 选择(Vue3 + ElementPlus)
前端·javascript·vue.js
巴博尔1 天前
uniapp的IOS中首次进入,无网络问题
前端·javascript·ios·uni-app
焚 城1 天前
UniApp 实现双语功能
javascript·vue.js·uni-app
被巨款砸中1 天前
前端 20 个零依赖浏览器原生 API 实战清单
前端·javascript·vue.js·web
文韬_武略1 天前
web vue之状态管理Pinia
前端·javascript·vue.js
董世昌411 天前
js怎样改变元素的内容、属性、样式?
开发语言·javascript·ecmascript
mosen8681 天前
【Vue】Vue Router4x关于router-view,transtion,keepalive嵌套写法报错
前端·javascript·vue.js