小程序 多线程Worker(类似h5的webWorker),小程序是单线程还是多线程

4747 1737 2022-10-16

本文讲了小程序 多线程Worker(类似h5的webWorker),小程序是单线程还是多线程。

一些异步处理的任务,可以放置于Worker中运行,待运行结束后,再把结果返回到小程序主线程。

Worker运行于一个单独的全局上下文与线程中,不能直接调用主线程的方法。

双方使用Worker.postMessage()来发送数据,Worker.onMessage()来接收数据

限制:

Worker最大并发数量限制为1个,创建下一个前请用Worker.terminate()结束当前Worker

Worker内代码只能require指定Worker路径内的文件,无法引用其它路径

Worker内不支持wx系列的API

Workers之间不支持发送消息

Worker目录内只支持放置js文件,其他类型的静态文件需要放在Worker目录外

插件使用worker前需要在plugin.json内配置workers代码路径,即一个相对插件代码包根目录的路径。

1、配置Worker

在app.json中可配置Worker代码放置的目录,目录下的代码将被打包成一个文件:

{

  "workers": "workers"

}

├── app.js

├── app.json

├── project.config.json

└── workers

    ├── request

    │   ├── index.js

    │   └── utils.js

    └── response

        └── index.js

2、在Worker指定文件中编写响应代码

worker.onMessage(function (res) {

  console.log(res)

})

3、在小程序主线程创建Worker对象

const worker = wx.createWorker('workers/响应代码文件',{

useExperimentalWorker:false

是否使用实验worker。在iOS下,实验worker的JS运行效率比非实验worker提升近十倍,如需在worker内进行重度计算的建议开启此选项。

同时,实验worker存在极小概率会在系统资源紧张时被系统回收,因此建议配合worker.onProcessKilled事件使用,在worker被回收后可重新创建一个

})

4、主线程给Worker发送消息

worker.postMessage({

  msg: 'hello worker'

})

5、监听worker线程被系统回收事件(当iOS系统资源紧张时,worker线程存在被系统回收的可能,开发者可监听此事件并重新创建一个worker

仅限在主线程worker对象上调用

worker.onProcessKilled(function callback)

6、结束当前Worker线程

仅限在主线程worker对象上调用

worker.terminate()

代码示例:

function createNewWorker() {

  const worker = wx.createWorker('workers/index.js', {

    useExperimentalWorker: true

  })

  // 监听worker被系统回收事件

  worker.onProcessKilled(() => {

    // 重新创建一个worker

    createNewWorker()

  })

}

// 创建实验worker

createNewWorker()

作为一个前端开发者,相信大家都知道JavaScript是单线程的,但是有没有想过为什么呢,为什么是单线程呢,我们去面试的时候也经常会被问到怎么理解单线程,甚至有部分开发者错误地把JavaScript的单线程理解成了浏览器也是单线程,OK,我们今天就来正正经经地捋一捋。

卷起袖子,听我娓娓道来。。。

JavaScript是单线程

首先,JavaScript的单线程与它的用途有关,作为浏览器语言,JavaScript的主要用途是与用户互动以及操作DOM,这决定了它只能是单线程,否则会带来很复杂的同步问题,比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准呢?

虽然HTML5引入了web worker,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM,所以,这个新标准并没有改变JavaScript单线程的本质。

浏览器是多线程

由于JavaScript是单线程,所有一些前端开发者误以为浏览器也是单线程,其实不是,浏览器是多线程的,浏览器为每个标签页开启了独立的渲染进程,每个进程之间的资源(CPU,内存等)和行为(UI,逻辑等)互不共享,所以即使某个标签页奔溃了也不会影响其他标签页。

而在每个标签页中,浏览器会把不同的工作交给对应的线程,比如GUI线程负责把HTML渲染成可视化的UI,JavaScript引擎线程负责解析和运行JavaScript代码逻辑,定时触发器线程负责处理setTimeout/setInterval定时器。

敲黑板,很多人以为setTimeout和setInterval是JavaScript的一部分,其实并不是,他们是运行时(最初是浏览器,后来node.js也提供了支持)提供的能力

我们知道,如果遇到网络慢的时候,有时候页面没办法完全加载出来,这是因为浏览器的GUI渲染线程和JavaScript引擎线程之间的互斥,阻塞的管理方式,JavaScript在执行期间会阻塞UI的渲染,甚至如果脚本执行时间太长会由于页面长时间无响应而奔溃。

为什么浏览器的GUI渲染线程和JavaScript引擎线程要互斥呢,本是同根生相煎何太急呀?

主要原因是,我们强大的JavaScript有修改DOM的权限!!!

当JavaScript代码被执行的时候,GUI渲染进程就会被挂起,等待JavaScript引擎进程空闲了再被执行,以免在渲染期间被JavaScript重复修改DOM造成不必要的渲染压力,采用互斥的的模式等待JavaScript代码执行完毕之后,可以保证渲染是最终的执行结果。

所以浏览器的空闲时长也成了衡量网站性能的重要指标之一,空闲时长多代表JavaScript逻辑密集以及DOM改动频率低,这种情况下浏览器可以更快速顺畅地响应用户的交互行为。

也是因为GUI线程和JavaScript引擎线程的这种互斥的方式,导致一些开发者误以为浏览器是单线程的。

微信小程序是双线程的

小程序的宿主是微信,但是小程序版本的迭代是独立的,升级更新不依赖宿主,这一点跟web网站是相同的,也就是说,小程序沿袭了web的某些优势,但是小程序并不是web,因为小程序的定位是小而美,用完就走,所以不追求在微信中实现全部的web能力,所以和web来比能力上肯定差一些,同时具备一些微信提供的原生能力,比如原生组件,系统级别和微信生态的API等等。

另外,小程序与微信的关系和网站和浏览器的关系不同,更接近codePen、JSFiddler这类在线编程平台中每个程序案例与平台的关系。

从技术的角度上,平台最核心的一个考量点是为案例提供足够能力的前提下,保证案例的逻辑不会危及平台的安全,说得直接点,就是你开发出来的小程序不能改动到宿主微信,也就是所谓的线程安全。

除了保证安全之外,还得考虑性能的问题,于是微信小程序根据以下几点技术需求采用了双线程的模型:

限制UI组件类型,只允许声明指定的几个组件

保证逻辑线程安全,不允许直接操作UI组件

能够在线更新,不依赖微信

小程序的宿主是微信,如果使用纯native实现,那么小程序的版本更新必须依赖微信,跟微信的代码一起发版,这样肯定是不行的,如果是纯web实现,安全和性能就很难得到保障。

小程序需要既能够像web一样将资源托管在云端,更新独立;同时又能够保证足够好的安全性和性能,最终小程序采用了hybrid-混合的架构模式:使用webview渲染UI,使用类似web worker的独立线程运行逻辑,这就是小程序的双线程模型。

小程序的双线程指的是渲染线程和逻辑线程,这两个线程分别承担UI的渲染和执行JavaScript代码的工作。

image.png

渲染线程使用webview进行UI的渲染呈现,webview是一个完整的类浏览器运行环境,本身具备运行JavaScript的能力,但是小程序并不是将逻辑脚本放到webview中运行,而是将逻辑层独立为一个与webview平行的线程,使用客户端提供的JavaScript引擎运行代码,,iOS的JavaScriptCore、安卓是腾讯X5内核提供的jsCore环境以及IDE工具的nwjs。

并且逻辑线程是一个只能够运行JavaScript的沙箱环境,不提供DOM操作相关的API,所以不能直接操作UI,只能够通过setData更新数据的方式异步更新UI。

基于小程序的双线程模式,我们在开发小程序中应该:

在保证功能的前提下尽量使用结构简单的 UI;

尽量降低 JavaScript 逻辑的复杂度;

尽量减少 setData 的调用频次和携带的数据体量

上文就是小编为大家整理的小程序 多线程Worker(类似h5的webWorker),小程序是单线程还是多线程。

国内(北京、上海、广州、深圳、成都、重庆、杭州、西安、武汉、苏州、郑州、南京、天津、长沙、东莞、宁波、佛山、合肥、青岛)Finclip软件分析、比较及推荐。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:AppCan:基于混合模式的移动应用开发,移动混合模式应用开发方案
下一篇:什么是小程序容器,一文帮你搞透彻,小程序容器框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~