pdfjs源码学习(三)

pdfjs 线程通信(二)

本来今天想了解一下绘制过程的,结果卡在了通信上,哈哈哈哈,继续来学习一下messge_handler,当时直接略过了,没想到这里面还有个槛。

pdfj是如何获取页面的绘制数据的?

一通debug以后,我们可以看到,主线程向pdf线程发了个GetOperatorList的消息,用的是messageHandler上的sendWithStream方法


    const readableStream = this._transport.messageHandler.sendWithStream(
      "GetOperatorList",
      {
        pageIndex: this._pageIndex,
        intent: renderingIntent,
        cacheKey,
        annotationStorage: map,
        modifiedIds,
      },
      transfer
    );
    const reader = readableStream.getReader();

这个方法返回了一个ReadableStream的实例,两句话有点难讲清楚,简单介绍一下把。

 sendWithStream(actionName, data, queueingStrategy, transfers) {
    const streamId = this.streamId++,
      sourceName = this.sourceName,
      targetName = this.targetName,
      comObj = this.comObj;

    return new ReadableStream(
      {
        start: controller => {
          const startCapability = Promise.withResolvers();
          this.streamControllers[streamId] = {
            controller,
            startCall: startCapability,
            pullCall: null,
            cancelCall: null,
            isClosed: false,
          };
       ……

pdfjs自己实现了线程之间流的通信协议,将页面的数据转换成操作命令通过流的方式(分chunk)传输给了主线程。

具体可以看message_handler.js和operator_list.js的实现, operator_list定义了flush方法,内部调用了sink的enqueue方法,将命令分批传输出去。

这样不仅解决了线程通信之间数据量过大的问题,而且主线程不需要等到全部的流传输完毕就可以开始绘制pdf页面了(线程之间互不影响),very nice。

ps: 页面数据和操作命令的转换过程可以看一下evaluator.js中的实现。

既然页面的绘制命令都拿到了,想要画出来就简单啦。

下期再介绍吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值