最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Cesium是如何实现多线程的

    正文概述 掘金(moe_)   2021-06-21   554

    这是我参与更文挑战的第9天,活动详情查看: 更文挑战。

    Web Worker

    背景

    众所周知,JavaScript是单线程模型,所有的任务只能在同一条线程上进行完成,前边的任务未完成则后续任务只能等待,所以在H中引入了Web Worker,为JavaScript创建一个多线程的环境,将部分任务提供给它在后台运行,前台后台同时运行。

    Web Worker是后台运行的JavaScript,它独立于其他脚本且不会影响页面的性能。引入Web Worker的好处是一些计算密集型或高延迟的任务,被 Web Worker 线程所处理,主线程就会很流畅,不会被阻塞或拖慢,而此时 Web Worker 在后台运行。但是这也正是 Web Worker 比较耗费资源的原因。

    浏览器支持及使用

    除了IE外所有主流浏览器均支持Web Worker。

    可在创建Worker之前检测是否支持

    if(typeof(Worker)!=="undefined") {
        // 支持.....
    }
    else {
        // 不支持..
    }
    

    Web Worker在一个独立的线程中运行,所以代码需要放在一个单独的文件中。加载时如果存在指定文件,浏览器会在文件下载完毕后执行,生成新的Worker线程,如果加载文件失败不会有任何提示。

    创建Worker后利用postMessage()启动

    var worker = new Worker('worker.js');
    var info = 'start worker!'
    worker.postMessage(info);
    

    在Worker中使用onmessge事件接收主线程的消息来实现一些操作。

    onmessage = function(e) {
        var data = e.data
    }
    

    同样的,从Worker发消息到主线程也采用同样方法。

    // Receive the message from the main thread
    onmessage = function(e) {
        var info = e.data;
        var result = info + ' get';
        postMessage(result);
    };
    

    停止Worker有两种方法,在主线程中调用worker.terminate()或在内部调用self.close()均可。在任务结束后一定要停止,因为Worker会一直在后台运行耗费资源,不应该过度使用。

    注意事项

    • 主线程与Worker之间传递的消息不是共享的,因为系统将消息对象传递给Worker后会将其序列化,在另一端再取消序列化。大部分浏览器通过JSON的编码解码实现。
    • Worker的self和this都是Worker的全局作用域。
    • Worker无法处理DOM,无法使用window对象、document对象等。
    • Worker可以生成子Worker,但需要注意:子Worker必须和父线程处在相同origin中,其中的URI应相对于父Worker位置解析。

    Cesium的异步+多线程

    Cesium中涉及到大量三维球计算和大数据量交互,比如三角网,参数化Geometry等,都是在Worker中实现的,参数的传递以及不同类型对应的不同算法。

    Cesium源码中Source\Core\TaskProcessor.js内为Cesium封装的Worker。我们简单来看一下。

    function TaskProcessor(workerPath, maximumActiveTasks) {
        this._workerPath = new Uri(workerPath).isAbsolute()
            ? workerPath
        : TaskProcessor._workerModulePrefix + workerPath;
        this._maximumActiveTasks = defaultValue(
            maximumActiveTasks,
            Number.POSITIVE_INFINITY
        );
        this._activeTasks = 0;
        this._deferreds = {};
        this._nextID = 0;
    }
    
    
    TaskProcessor.prototype.scheduleTask = function (
    parameters,
     transferableObjects
    ) {
        if (!defined(this._worker)) {
            this._worker = createWorker(this);
        }
    
        // ……
    
    
        return when(canTransferArrayBuffer(), function (canTransferArrayBuffer) {
            // ……
    
            return deferred.promise;
        });
    };
    

    我们使用时只需要创建一个TaskProcessor,指定类型,然后调用scheduleTask,接收对应具体参数,然后返回一个Promise对象,我们可以异步的获取的对应结果。

    使用方法:

    var taskProcessor = new Cesium.TaskProcessor('myWorkerPath');
    var promise = taskProcessor.scheduleTask({
        someParameter : true,
        another : 'hello'
    });
    if (!Cesium.defined(promise)) {
        // too many active tasks - try again later
    } else {
        Cesium.when(promise, function(result) {
            // use the result of the task
        });
    }
    

    起源地下载网 » Cesium是如何实现多线程的

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元