Javascript 异步功能头脑风暴-巴贝尔

Javascript 异步功能头脑风暴-巴贝尔,javascript,asynchronous,babeljs,Javascript,Asynchronous,Babeljs,嘿,我认为这更多的是头脑风暴的帮助,如果它违反了规则,那么很抱歉。只是不知道去哪里问这个 背景故事 我正在使用React,并使用Babel传输ES6/7。我要做的是让另一个类的组件调用一个函数来通知它需要更改的应用程序状态。我希望这个函数调用立即返回,而不是阻塞以下所有逻辑 迄今为止的想法 1我知道有承诺,但我觉得这会使电话太大而无法书写。考虑到发生在外部的操作不会返回任何纯粹的结果,也不会抛出调用类需要注意的错误。据我所知,我必须这样做才能调用这个分派函数。。。 另一类调度 .then=>{}

嘿,我认为这更多的是头脑风暴的帮助,如果它违反了规则,那么很抱歉。只是不知道去哪里问这个

背景故事 我正在使用React,并使用Babel传输ES6/7。我要做的是让另一个类的组件调用一个函数来通知它需要更改的应用程序状态。我希望这个函数调用立即返回,而不是阻塞以下所有逻辑

迄今为止的想法

1我知道有承诺,但我觉得这会使电话太大而无法书写。考虑到发生在外部的操作不会返回任何纯粹的结果,也不会抛出调用类需要注意的错误。据我所知,我必须这样做才能调用这个分派函数。。。 另一类调度 .then=>{} .catchconsole.error 但这似乎是毫无理由的陈词滥调

2有异步函数decorator,但我的印象是,这些函数需要返回一个承诺,并使用wait关键字进行解析。对我来说,这听起来仍然像是阻塞,或者使用了promise-then模式

4我想到了一种混合,这样调用函数只发出分派函数,然后被调用函数将执行承诺。如果我没有弄错,操作似乎应该跳过承诺并返回,而承诺随后将异步触发,但我不确定是这种情况,还是最佳路径

function dispatch( ) {  
   new Promise((resolve, reject) => {  
      ...  
   }).then(() => {})  
     .catch(console.error)  
}  

dispatch();  
5使用队列类型数组和无限轮询循环的老式方法。调用dispatch只是将请求推送到队列的末尾,循环可能使用requestAnimationFrame轮询数组并按顺序完成它们。我担心这可能会在脆弱的情况下损坏cpu/电池,比如将其移植到React Native,在移动设备上运行

我应该注意到速度是关键。5有一个很好的方法,因为它保持了更改的有序性,但这感觉很奇怪。

您的Promise版本可以简单得多:

function dispatch() {
    Promise.resolve().then(doTheRealWork);
}
这将是异步的;永远不会拒绝,除非doTheRealWork拒绝/抛出,并且你已经说过不会,所以不需要捕获;它将在大多数浏览器上调度后尽快调用doTheRealWork async,作为当前宏任务完成后的一个微任务

当然,你可以给自己一个更简洁的实用方法:

const later = callback => Promise.resolve().then(callback);

例如:

const later=callback=>Promise.resolve.thencallback; 功能分派{ 侧向工作; } 函数doTheRealWork{ 做真正的工作; } 控制台.日志调用调度; 派遣
console.logBack来自调度 根据评论中的建议,我做了一个快速的测试。事实上,我对这个答案感到惊讶,这就是为什么如果有人关心或偶然发现这个问题,我会分享它

测试设置

我使用的是react,所以我刚刚生成了一个视图,其中包含1000个简单组件和随机着色的方块,所有这些方块都通过一个回调函数监听更新,该回调函数会改变它们的颜色。在processAction函数期间。performance.now用于跟踪从进程开始到进程结束的时间戳所有组件的回调都已被调用。一个按钮触发dispatchAction功能以启动流程

方法

我减少了按钮的按下,因为它只是调用dispatchAction;processAction导致它只是在数组中循环并随机化,然后调用它已注册的回调,因此在此过程中没有更改数组中的任何代码

1.原始的阻塞方法

function dispatchAction() {
    this.processAction(); //This used to be all in dispatchAction but I moved it for tests
}
最终性能:平均5-7毫秒

2 T.J.Crowder的建议

function dispatchAction() {
   Promise.resolve().then(() => this.processAction()) //Used the anon-call because I may use parameters
}
产生的性能:80-110毫秒平均值为什么

3赛斯·怀特评论中的建议

function dispatchAction() {
   return new Promise((resolve, reject) => {
      this.processAction()
      resolve()
   }
}
最终性能:平均4-7毫秒


因此,3回报一个承诺,不做任何事情,然后或捕获实际上是辉煌的工作。保持异步,并且至少将性能报告保持在原始状态。

软件工程交换将是发布此报告的更好地方。我看到这一点很快就会被否决/删除。可能想更改标题,使其更具吸引力specfic@SethWhite真正地那实际上可能是个好办法。但我有时看到承诺往往会捕获任何错误,不管调用在哪里,然后我会得到未解决的异常错误。@CP510当然,只要在控制台中尝试以下操作:let thing==>new Promiseresolve,reject=>{console.log'asdf';resolve77};console.log将始终输出,您可以选择调用。然后获取解决方案。如果你从未使用过承诺,那么回复承诺没有多大意义,但这是可能的。@bholagabar在引用其他网站时,指出我将尝试一下这一点通常是有帮助的!谢谢你的建议,我不知道这个模式
function dispatchAction() {
   return new Promise((resolve, reject) => {
      this.processAction()
      resolve()
   }
}