在knockoutjs-vewmodel的后台运行的Worker
A Worker running in the background for knockoutjs vewmodel
我有一个用于knockoutjs组件的视图模型。在视图模型中,有一个执行数分钟的函数init()
。因此,浏览器上组件的UI将冻结,直到init()
完成执行为止。
function myViewModel(){
self = this;
self.x = ko.observable(0);
self.y = ko.observableArray([]);
self.z = ko.observable({});
self.init = function(){
//Need to use JQuery here
//loading stuff from DB via JQuery ajax
//assign retrieved data to x and y and z
}
}
有没有办法在后台运行init()
?
我研究了Worker
的可能性,它在后台运行,但Worker
需要使用JQuery。如果我通过postMessage将JQuery(和其他几个JSON对象(传递给worker,比如:worker.postMessage($)
,那么我会得到错误:
无法在"Worker"上执行"postMessage":无法克隆对象
知道如何让init()
在后台运行以避免UI冻结吗?
我尝试了超时,如下所示,但UI仍然冻结:
self.executeAsync = function(func) {
setTimeout(func, 0);
};
self.executeAsync(self.init);
您可以使用promise。
至于注释,您的问题是您知道如何使用所有ajax承诺,但不知道如何实现自己的承诺。
在使用jQuery时,让我们使用这个库。只需3步
- 创建一个延迟对象,如下所示:
var deferred = $.Deferred();
- 从这个延迟返回一个promise,这样您就可以使用
.then
在promise被解析或拒绝时包含回调。例如:return deferred.promise();
,或者,如果您返回和object,您可以作为该object的成员返回promise,以检查是否完成:return { ..., promise = deferred.promise()};
- 当您的代码成功或失败时,解决或拒绝您的承诺,如下所示:
deferred.resolve();
或deferred.reject();
在您的情况下,在init()
开始时创建一个deferred,当所有jQueryajax都完成时,解决promise,或者如果出现问题,则拒绝它。
关于Deferred
功能的一些注意事项:
- 如果您解析(或拒绝(延迟传递的对象,您将接收该对象作为回调的参数
- 您可以返回一个包含在promise中的对象。例如,如果
init()
返回一个对象(例如实现API的对象(,则可以返回包装在promise中的对象,如下所示:return deferred.promise(retVal);
- jQuery promise的实现直到3.0版本才与promises/A+兼容。这与回调链中的链接和异常传播有关。对于这种情况,它不会影响你。同时,您可以使用其他promise库,如Q或rsvp,它们与promises/A+兼容,并实现更多功能
- 您可以使用
deferred.notify
来表示进度。然后可以指定progress
回调
jQuery的Deferred对象的文档。
伪代码:
init: function() {
var deferred = $.Deferred();
// run your stuff, for example with setTimeout() or setInterval()
// so that the code follows running on the same line
// eventually, your stuff will resolve or reject the deferred/promise
return deferrer.promise();
}
然后,您可以像往常一样在init中使用回调:init().then(...)
;
由于您没有解释init函数的作用,因此不清楚当promise被解析时,您是否必须更新一些可观察性,或显示一些控件或其他什么。这取决于你。
注意:如果使用jQuery操作DOM对象,恐怕会出错:在使用knockout时,所有DOM操作都应该使用ko绑定来解决。混合使用这两种DOM操作方式很快就会变得麻烦。
您可以使用importScripts()
将jQuery导入到Worker
脚本中。
在Worker
脚本的顶部,只需放置importScripts('path/to/jQuery')
,就可以访问jQuery。importScripts
函数是WorkerGlobalScope
接口中的全局函数,因此您的所有工作人员都应该可以访问它。
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- 使用压缩的JavaScript文件(不是运行时压缩)
- Javascript运行php文件,然后下载文件
- chrome扩展:尽管运行了at:documentidle,js脚本还是过早启动
- 我已经创建了一个jquery转盘,并使用if条件来运行和停止转盘
- Angularjs代码未在匿名函数中运行
- jquery设置为使用参数运行
- 如何根据时间运行不同的脚本
- 当我尝试运行mocha测试时,没有定义Worker
- 当浏览器关闭时,运行Web Worker会发生什么情况
- JavaScript 函数可以检查它是否在 Web Worker 线程上运行吗?
- 加载远程Service Worker,以便在其他域中运行
- 在Tizen web应用程序中,我可以使用javascript web worker在封闭的应用程序上运行后台代码吗?
- 识别JS脚本何时作为Worker运行
- Chrome v54中的Web worker在非活动选项卡中运行时速度慢两倍
- 在knockoutjs-vewmodel的后台运行的Worker
- 是一个Web Worker比运行脚本更快
- 在web worker仍在运行时向其发送消息
- service worker是否会在浏览器关闭的情况下在后台运行?
- Worker可以在Firefox和旧版本的Chrome上运行,但不能在最新版本的Chrome上运行