我有一个巨大而缓慢的同步函数,我希望将它包装在一个承诺中,以异步方式使用它。虽然这个函数包含二次操作,但是在不使界面卡住的情况下执行是很好的(避免用户愤怒:D)。
我所做的是以下(commons.js,单独的javascript文件):
exports default {
myHugeFunction: function(params) {
//lots...lots...lots..of synchronous things
}
}
我称之为什么?
Vuejs商店模块
import commons from '/path/to/commons'
export default {
actions: {
updateInterface: function() {
//overlay on
//some syncronous stuff...
Q.fcall(function () {
commons.myHugeFunction(params);
}
//some others syncronous stuff...
//overlay off
}
}
}
即便如此,似乎工作正常,但是由于庞大的功能已经完成,我整个前端都被卡住了。我用来在执行之前和之后放置一个叠加但是如果在dom中我无法看到它(但这可能是另一个超出范围的问题......)。
我认为它的执行就像可以由一个单独的线程处理的东西,所以在这段时间内,用户可以做其他事情。
是因为“也许”应用程序完全位于前端(浏览器)?
答案 0 :(得分:0)
您可以使用Web工作者,条件是 myHugeFunction 不使用仅在window
上下文中可用的任何全局变量。因此,例如,它无法与DOM交互。您需要将所有外部依赖项作为参数传递,或者在Web worker上下文中包含依赖项。
以下是它的样子:
将 myHugeFunction 从commons.js
移出到一个不应该worker.js
的新的单独import
文件中。您的worker.js
文件应如下所示:
function myHugeFunction(...params) {
//lots...lots...lots..of synchronous things
console.log('parameters', params);
return 'myHugeFunction return value';
}
onmessage = function(e) {
postMessage(myHugeFunction(...e.data));
}
在commons.js
中,您可以定义此辅助函数promiseWork
:
exports default {
promiseWork: function(script, params) {
return new Promise(function (resolve, reject) {
var worker = new Worker(script);
worker.onmessage = function(e) {
resolve(e.data);
}
worker.onerror = function(e) {
reject('[' + e.filename + ':' + e.lineno + '] ' + e.message);
}
worker.postMessage(params);
});
}
}
在您的Vuejs商店模块中,您可以使用脚本名称和参数(数组)作为参数调用promiseWork
:
export default {
actions: {
updateInterface: function() {
//overlay on
//some synchronous stuff...
promiseWork('worker.js', params).then(function () {
console.log('huge work completed asynchronously');
//some other stuff...
//overlay off
});
}
}
}