我有一个knockoutjs组件的viewmodel。在viewmodel中,有一个函数init()
可以执行几分钟。因此,浏览器上组件的UI冻结,直到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
在后台运行的可能性,但worker.postMessage($)
需要使用JQuery。如果我通过postMessage将JQuery(以及其他几个JSON对象)传递给worker,如下所示:init()
,那么我收到错误:
无法在'Worker'上执行'postMessage':无法克隆对象。
知道如何让self.executeAsync = function(func) {
setTimeout(func, 0);
};
self.executeAsync(self.init);
在后台运行以避免冻结用户界面吗?
我尝试了超时,如下所示,但UI仍然冻结:
Employee
答案 0 :(得分:1)
你可以使用承诺。
至于评论,你的问题是你知道如何使用所有的ajax承诺,但你不知道如何实现自己的承诺。
当你使用jQuery时,让我们用这个库来做。这只是3个步骤
var deferred = $.Deferred();
.then
包含回调。例如:return deferred.promise();
或者,如果您要返回并且是对象,则可以将该承诺作为该对象的成员返回,以检查完成情况:return { ..., promise = deferred.promise()};
deferred.resolve();
或deferred.reject();
在你的情况下,在init()
的开头创建一个延迟,当所有的jQuery ajax都完成后,解决这个问题,或者如果出现问题就拒绝它。
有关Deferred
功能的一些说明:
init()
返回一个对象(例如实现API的对象),您可以返回包含在这样的承诺中的对象:return deferred.promise(retVal);
deferred.notify
表示进度。然后,您可以指定progress
回调伪代码:
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函数的作用,因此不清楚是否必须更新某些observable,或者在解析promise时显示某些控件或其他内容。这取决于你。
注意:如果你使用jQuery操作DOM对象,我担心你可能做错了什么:当使用knockout时,所有的DOM操作都应该用ko绑定来解决。混合两种DOM操作方式很快就会变得很麻烦
答案 1 :(得分:0)
您可以使用Worker
将jQuery导入importScripts()
脚本。
在Worker
脚本的顶部,只需添加importScripts('path/to/jQuery')
,您就可以访问jQuery了。 importScripts
函数是WorkerGlobalScope
接口中的全局函数,因此您的所有工作者都应该可以访问它。