MST

星途 面试题库

面试题:Node.js 结合 EventEmitter 实现异步任务取消

假设你正在开发一个Node.js应用,其中有一个复杂的异步任务,该任务由多个子异步操作组成,这些操作基于回调函数实现。现在需要你引入EventEmitter机制,实现能够随时取消这个复杂异步任务的功能。请描述实现思路并给出关键代码示例。
50.2万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建一个EventEmitter实例,用于触发取消事件。
  2. 在每个子异步操作中,监听取消事件。当接收到取消事件时,中断当前操作并处理后续逻辑。
  3. 为复杂异步任务提供一个公开的取消方法,通过触发EventEmitter的取消事件来取消整个任务。

关键代码示例

const EventEmitter = require('events');

class ComplexAsyncTask extends EventEmitter {
    constructor() {
        super();
        this.canceled = false;
    }

    // 模拟子异步操作
    subAsyncOperation1(callback) {
        setTimeout(() => {
            if (this.canceled) {
                return callback(new Error('任务已取消'));
            }
            callback(null, '操作1完成');
        }, 1000);
    }

    subAsyncOperation2(callback) {
        setTimeout(() => {
            if (this.canceled) {
                return callback(new Error('任务已取消'));
            }
            callback(null, '操作2完成');
        }, 1000);
    }

    // 复杂异步任务
    execute() {
        this.subAsyncOperation1((err, result1) => {
            if (err) {
                if (err.message === '任务已取消') {
                    return console.log('任务取消,操作1中断');
                }
                return console.error('操作1错误:', err);
            }
            console.log(result1);

            if (this.canceled) {
                return console.log('任务取消,不再执行操作2');
            }

            this.subAsyncOperation2((err, result2) => {
                if (err) {
                    if (err.message === '任务已取消') {
                        return console.log('任务取消,操作2中断');
                    }
                    return console.error('操作2错误:', err);
                }
                console.log(result2);
            });
        });
    }

    cancel() {
        this.canceled = true;
        this.emit('cancel');
        console.log('任务已取消');
    }
}

// 使用示例
const task = new ComplexAsyncTask();
task.execute();

// 模拟在某个时刻取消任务
setTimeout(() => {
    task.cancel();
}, 1500);