在action vuex中调用异步函数

时间:2017-05-15 16:19:46

标签: javascript promise vue.js vuejs2 vuex

我有一个巨大而缓慢的同步函数,我希望将它包装在一个承诺中,以异步方式使用它。虽然这个函数包含二次操作,但是在不使界面卡住的情况下执行是很好的(避免用户愤怒: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中我无法看到它(但这可能是另一个超出范围的问题......)。

我认为它的执行就像可以由一个单独的线程处理的东西,所以在这段时间内,用户可以做其他事情。

是因为“也许”应用程序完全位于前端(浏览器)?

1 个答案:

答案 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
            });
        }
    }
}