Javascript 在等待异步任务时是否永远循环?

Javascript 在等待异步任务时是否永远循环?,javascript,web-worker,Javascript,Web Worker,我想知道是否有一种方法可以让JavaScript在继续使用事件和循环之前等待一些可变长度的代码执行完成。在回答使用超时、回调或引用此作为副本之前,请先听我说完 我想向web工作者公开一个大型API。我希望这个API感觉是“原生的”,即您可以使用从另一个线程获取信息的getter访问每个成员。我最初的想法是编译API并在worker上重建整个对象。虽然这是一个非常有趣的项目,但它在启动时速度很慢,无法显示对API所做的更改,除非在修改后再次将其发送给工作人员。观察者可以解决部分问题,而web工作者

我想知道是否有一种方法可以让JavaScript在继续使用事件和循环之前等待一些可变长度的代码执行完成。在回答使用超时、回调或引用此作为副本之前,请先听我说完

我想向web工作者公开一个大型API。我希望这个API感觉是“原生的”,即您可以使用从另一个线程获取信息的getter访问每个成员。我最初的想法是编译API并在worker上重建整个对象。虽然这是一个非常有趣的项目,但它在启动时速度很慢,无法显示对API所做的更改,除非在修改后再次将其发送给工作人员。观察者可以解决部分问题,而web工作者可转移对象可以解决所有问题,但它们还没有被广泛采用

由于工作者往返调用发生在几毫秒之内,我认为将线程暂停几毫秒可能是一个不错的解决方案。当然,我会考虑在通话时间过长的情况下终止通话,但我会首先尝试创建一个概念证明

假设我想向工作者公开api对象。我将为self.api定义一个getter,它将获取第一层属性。然后,每个属性将成为另一个getter,该过程将继续,直到找到最终的对象

worker.js

self.addEventListener'message',functionevent{ self.datareceived=true; self.data=event.data;//实际上会在这里构建新的getter }; Object.definePropertyself,“api”{ get:函数{ self.datareceived=false; self.postMessage“请求api第一层属性”; 而!self.datareceived; return self.data;//从主机接收的任何属性 } }; 对于实验,我们将进行一次简单的往返,无需数据处理:

仅index.html JS部分

var-worker=new Workerworker.js; worker.onmessage=函数{ worker.postMessage; }; 如果onmessage会中断循环,脚本理论上应该可以工作。然后工作人员可以动态访问window.document.body.style等对象

我的问题可以归结为:有没有一种方法可以保证事件会中断正在执行的代码块


根据我对JavaScript中事件的理解,我认为它们确实中断了当前线程。这不是因为它一遍又一遍地执行一个空白语句吗?如果我生成要执行的代码并一直这样做直到数据返回,那会怎么样?

据我所知,JS中没有什么东西可以这样做,但做类似的事情相对容易。不久前我为自己做了一个:

您可以像使用when-condition一样使用它,callback-where-condition是一个函数,当您的条件满足时,它应该返回true,而callback是您当时想要执行的函数

有没有办法保证事件会中断正在执行的代码块

正如@slebetman在评论中所建议的,不,不是在浏览器的web worker中运行的Javascript中,我可以想到一个可能的例外,请参见建议3。下面

我的建议,按优先顺序递减:

放弃感觉自己是本地人的愿望,或者也许本地人可能是一个更好的术语。您所建议的无限while循环似乎也在与Javascript提供的协作多任务环境作斗争,包括考虑单个web工作者时

Javascript中工作人员之间的通信是异步的。也许它会失败,需要的时间超过几毫秒。我不确定您的用例是什么,但我的感觉是,当项目增长时,您可能希望将这些毫秒用于其他用途

您可以更改已定义的属性以返回承诺,然后调用方将对响应执行.then操作以检索值,就像任何其他异步API一样

角度量角器/Webdriver有一个API,它使用con通过始终传递承诺来模拟使用承诺的同步环境。从

据我所知,上面的每一行都向控制流添加了异步执行的承诺。title实际上不是title,而是一个解析为title的承诺。虽然它看起来像是同步代码,但获取和测试都是在稍后异步进行的

您可以在web worker中实现类似的功能。然而,我确实想知道这是否值得努力。有很多代码可以做到这一点,我忍不住觉得主要的后果是,使用它编写代码会变得更难,而不是更容易,因为会有很多隐藏的行为

据我所知,在Javascript中唯一可以实现同步的是将async参数设置为false时的XMLHttpRequest。我想知道你是否能来 提出了一种向服务器请求的方法,该服务器维护与主线程的连接,并以此方式传递数据。我不得不说,我的直觉是,这是一个非常糟糕的想法,而且比仅仅从主线程请求数据要慢得多


我不打算把这当作一个答案,因为这不是你想听的。事件不会中断当前线程。相反,线程运行所有javascript代码,直到没有其他代码可运行为止,然后eventloop运行处理事件。所以它的“执行->处理事件->执行->处理事件…”。。。永远没有中断如果你一直执行代码直到数据返回,那么数据永远不会返回这里的“永不”意味着直到宇宙的热死或你的计算机被破坏,或者当你终止进程,以先到者为准。这是因为您从不允许eventloop运行,因此事件永远不会发生
browser.get(url);
var title = browser.getTitle();
expect(title).toEqual('My Title');