【问题标题】:Call asynchronous function inside action vuex在动作 vuex 中调用异步函数
【发布时间】:2017-05-15 16:19:45
【问题描述】:

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

我认为它的执行类似于可以由单独的线程处理的东西,因此用户在此期间可以做其他事情。

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

【问题讨论】:

  • 无论你把它放在哪里,如果你有一个巨大的同步函数阻塞 io,它就会阻塞 io。修复函数本身。
  • 非常感谢您的有用回答!现在问题很清楚了。这是与另一个为他的工作感到非常自豪的团队共享的代码:D 并且由于任何原因(该代码)都无法触摸,所以我们必须解决这个问题,这也可能吗?是或否也可能是一个很好的答案,只是为了知道我们如何从现在开始:)

标签: javascript promise vue.js vuejs2 vuex


【解决方案1】:

您可以为此使用网络工作者,条件是 myHugeFunction 不使用任何仅在 window 上下文中可用的全局变量。例如,它不能与 DOM 交互。您需要将所有外部依赖项作为参数传递,或者将依赖项包含在 Web Worker 上下文中。

下面是它的样子:

myHugeFunctioncommons.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
            });
        }
    }
}

【讨论】:

    猜你喜欢
    • 2020-05-17
    • 2019-01-20
    • 1970-01-01
    • 2020-03-09
    • 2021-12-25
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    相关资源
    最近更新 更多