js三座大山之异步六实现微任务的N种方式

异步编程

js三座大山之异步一单线程,event loope,宏任务&微任务
js三座大山之异步二异步方案
js三座大山之异步三promise本质
js三座大山之异步四-Promise的同步调用消除异步的传染性
js三座大山之异步五基于异步的js性能优化
js三座大山之异步六实现微任务的N种方式

js中现在有两类任务

一类是天然存在的在当前执行栈中按顺序依次执行的同步任务

一类是为了解决单线程带来的问题引入的异步任务

宏任务和微任务主要的区别体现在执行时机上,当事件循环每次执行完一个宏任务时,它会检查是否有微任务队列。如果有,那么在下一个宏任务开始之前,事件循环会一直执行微任务队列中的所有任务。也就是说,微任务的优先级高于宏任务,微任务会在任何新的宏任务开始之前执行,并且直至微任务被清空后才会执行下一个宏任务

宏任务和微任务根据不同的触发方式 在执行时机上有所不同 其他并无区别。并不是说微任务执行性能好于宏任务。

微任务一般由JavaScript引擎发起。

宏任务一般由宿主环境(如浏览器或Node.js)发起。

实现异步微任务的N种方式

promise

scss 复制代码
Promise.resolve().then(callback);

这个大家都知道而且是最常用的 在之前的文章中也有讲解过promise的本质 这里不再解释。

queueMicrotask

queueMicrotask api在浏览器和node环境都支持。是一个全局的方法,它接受一个回调函数作为参数,并将这个回调函数放入微任务队列中。

javascript 复制代码
queueMicrotask(()=>{
    console.log('queueMicrotask')
})

MutationObserver 浏览器环境

MutationObserver是一个可以用来监视DOM变化的API。当你使用MutationObserver创建一个观察者并开始观察某个DOM元素时,每当这个元素或其子元素发生变化,MutationObserver就会将你提供的回调函数添加到微任务队列中。

ini 复制代码
        const callback = () => {
            console.log('test MutationObserver')
        }
        const observer = new MutationObserver(callback);
        const element = document.createTextNode("");
        observer.observe(element, {
            characterData: true,
        });
        const change = () => {
            element.data = `${Date.now()}`;
        };
        change();

process.nextTick node环境

process.nextTick是Node.js特有的API,它的回调函数会在当前操作完成后,下一个事件循环开始前立即执行,也是微任务的一种。

arduino 复制代码
process.nextTick(() => {
    console.log('nextTick');
});

微任务代码总结

javascript 复制代码
const micros = [
    {
        name: 'queueMicrotask',
        test: () => {
            return typeof queueMicrotask === "function";
        },
        run: (callback: Task) => {
            queueMicrotask(callback);
        },
    },
    {
        name: 'Promise',
        test: () => {
            return typeof Promise !== "undefined";
        },
        run: (callback: Task) => {
            Promise.resolve().then(callback);
        },
    },
    {
        name: 'process.nextTick',
        test: () => {
            return (
                typeof process === "object" && typeof process.nextTick === "function"
            );
        },
        run: (callback: Task) => {
            process.nextTick(callback);
        },
    },
    {
        name: 'MutationObserver',
        test: () => {
            return (
                typeof MutationObserver !== "undefined" && typeof window !== "undefined"
            );
        },
        run: (callback: Task) => {
            const observer = new MutationObserver(callback);
            const element = document.createTextNode("");
            observer.observe(element, {
                characterData: true,
            });
            const change = () => {
                element.data = `${Date.now()}`;
            };
            change();
        },
    },
];

export const microTask = (callback: Task) => {
    const runner = [...micros].find((item) => item.test());
    runner && runner.run(callback);
};

github源码

相关推荐
ShineWinsu7 小时前
对于C++:类和对象的解析—下(第二部分)
c++·面试·笔试·对象··工作·stati
码农水水8 小时前
国家电网Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·网络·分布式·面试·wpf
集成显卡8 小时前
Bun v1.3.6 发布:内置 Tarball 归档支持、JSONC 解析、Bundle 分析增强等重磅更新!
javascript·新版本·bun.js
奔跑的web.8 小时前
TypeScript Enum 类型入门:从基础到实战
前端·javascript·typescript
盐真卿9 小时前
python2
java·前端·javascript
梦梦代码精9 小时前
BuildingAI vs Dify vs 扣子:三大开源智能体平台架构风格对比
开发语言·前端·数据库·后端·架构·开源·推荐算法
seabirdssss10 小时前
《bootstrap is not defined 导致“获取配置详情失败”?一次前端踩坑实录》
前端·bootstrap·html
kgduu10 小时前
js之表单
开发语言·前端·javascript
码农水水11 小时前
京东Java面试被问:HTTP/2的多路复用和头部压缩实现
java·开发语言·分布式·http·面试·php·wpf
摘星编程11 小时前
React Native for OpenHarmony 实战:Picker 选择器组件详解
javascript·react native·react.js