Vue 中 MathJax 的使用与渲染的监听 (下)

本文探讨了在Vue组件中监听和管理MathJax渲染,包括使用MathJax.Hub.Queue深入理解,提出并解决了在多组件实例中MathJax渲染监听可能存在的问题,通过自定义TypesetQueue和相关Mixin实现对MathJax渲染进度的控制,以满足在打印前等待所有公式渲染完成的需求。
摘要由CSDN通过智能技术生成

在这里插入图片描述

本文作者:傅云贵(网易有道技术团队)


在上一篇文章 (见 Vue 中 MathJax 的使用与渲染的监听 (上) ) 中讲述了在 Vue 组件中如何使用 MathJax,却应对不了产品的新需求:

待 MathJax 渲染(Typeset)数学公式后,用户使用浏览器的打印功能打印网页。

在此需求中,需要判断所有组件实例的 MathJax Typeset 是否完成。

如何监听所有组件实例中的 MathJax Typeset 是否完成呢?

组件 typeset 渲染的监听初步实现

根据「分而治之」的思想,很容易想到:若要判断多个组件实例是否 MathJax typeset 完成,只要判断每一个组件实例是否 MathJax typeset 完成。

在组件中,我们可以使用以下方法监听 MathJax Typeset 是否完成。

@Component({})
class SomeComponent extends Vue {
    private mathJax: typeof MathJax | null = null

    private needTypeset: boolean = false

    isTypesetFinished: boolean = false

    private callMathJaxTypeset(): void {
        const { mathJax } = this
        if (mathJax) {
            const { typesetElement } = this.$refs
            mathJax.Hub.Queue(['Typeset', MathJax.Hub, typesetElement])
            mathJax.Hub.Queue(() => {
                this.isTypesetFinished = true
            })
        } else {
            this.needTypeset = true
        }
    }

    created(): void {
        const mathJax = await loadMathJax()
        this.mathJax = mathJax

        if (this.needTypeset) {
            this.callMathJaxTypeset()
        }
    }

    mounted(): void {
        this.isTypesetFinished = false
        this.callMathJaxTypeset()
    }

    updated(): void {
        this.isTypesetFinished = false
        this.callMathJaxTypeset()
    }
}

MathJax.Hub.Queue 深入了解

在组件实现 MathJax Typeset 是否完成过程中,使用了MathJax.Hub.Queue, 那么这个 Queue 究竟是什么呢?

翻阅 MathJax 的源码,可以发现 MathJax.Hub.Queue 源于 MathJax.Callback.Queue

// ...

var QUEUE = BASE.Object.Subclass({
    //
    //  Create the queue and push any commands that are specified
    //
    Init: function() {
        // ...
    },
    //
    //  Add commands to the queue and run them. Adding a callback object
    //  (rather than a callback specification) queues a wait for that callback.
    //  Return the final callback for synchronization purposes.
    //
    Push: function() {
        //...
    },
    //
    //  Process the command queue if we aren't waiting on another command
    //
    Process: function(queue) {
        // ...
    },
    //
    //  Suspend/Resume command processing on this queue
    //
    Suspend: function() {
        // ...
    },
    Resume: function() {
        // ...
    },
    //
    //  Used by WAITFOR to restart the queue when an action completes
    //
    call: function() {
        // ...
    },
    wait: function(callback) {
        // ...
    },
})
// ...

BASE.Callback.Queue = QUEUE

// ...

var HUB = BASE.Hub

// ...

HUB.queue = BASE.Callback.Queue()

MathJax.Hub = {
    // ...
    Queue: function() {
        return this.queue.Push.apply(this.queue, arguments)
    },
    //...
}

MathJax.Callback.Queue

A “callback” is a function that MathJax calls when it completes an action that may occur asynchronously (like loading a file). Many of MathJax’s functions operate asynchronously, and MathJax uses callbacks to allow you to synchronize your code with the action of those functions. The MathJax.Callback structure manages these callbacks.

MathJax.Callback.Queue 是一个队列,负责管理一系列 callback (即任务)的执行。MathJax.Hub.Queue 可以理解为 MathJax.Callback.Queue 的一个实例。

初步实现 typeset 渲染监听可能存在的问题

由于 MathJax.Hub.Queuecallback 是存储在队列的,并不会立即执行;且在实际使用过程发现, typeset 渲染数学公式过程并不太快。那么,组件 typeset 渲染的监听初步实现 章节中的实现,在多组件实例、多次updated的情况下,MathJax.Hub.Queue 中等待任务可能会出现以下情况:

<
序号 MathJax.Hub.Queue 中等待的任务
N+1 someComponent1 typeset callback
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值