我有很多我想要执行的同步函数,之前是基本的ajax请求,这些请求将把html渲染到DOM。
为了做到这一点,我必须同步执行所有这些
一一要求。但我不知何故希望这些同步功能同时异步,并等待它们完成以加快速度。这必须发生在同步函数内。但我的理解是这在 javascript 中不起作用,但我想听听你们要说什么。
所以我的尝试是将所有这些同步请求添加到异步承诺中,然后进行 Promise.all 调用。我等不及 Promise.all().then 因为主线程将在这个主同步线程/函数之后继续执行其余的代码。所以我想知道是否有一种方法可以阻止主线程以等待这些异步调用
这是我正在谈论的内容的简短说明
var syncfunc = () => {
var getPromise = () => {
return new Promise((resolve) => {
var asyncAjaxRequest = async function() {
doSomeStuff();
resolve();
}
})
}
var promises = [getPromse(), getPromse(), getPromse()];
Promise.all(promises);
console.log('i want this console.log to execute after all promises executed doSomeStuff');
/**
*
* Promise.all(promises).then(() => {
// I cant use this, because its script in other files that will execute if i wait like this
})
*/
}
我知道 .then 将在所有解析完成后执行,但我基本上想阻止此同步线程,等待所有其他异步完成。
如果可以的话,我当然会根据我的需要更改结构,但问题和我尝试这样做的原因是因为我使用 sitevision 框架,并且想要在打印模块打开打印窗口之前向 dom 添加一些内容。同步调用每个函数并不是正确的方法,它会很慢。我还尝试设置 window.print = null 来禁用打印功能,然后在 Promise 解析时将打印功能添加回来,但它根本不起作用
您无法使用纯 JavaScript(无需外部代码)将异步操作转变为同步操作。事件驱动的 JS 引擎并不是这样工作的。
根据定义,异步操作启动操作(将执行交给本机代码),然后返回到解释器,然后解释器继续执行后面的代码。当完成时,本机代码将向 JS 事件队列添加一个事件,以允许解释器事件循环为异步操作的完成提供服务。如果您创建某种“块”,例如半无限 while 循环,这将“阻止”解释器执行更多代码,那么您最终会陷入僵局。阻塞解释器的循环会阻止 JS 解释器处理指示异步操作结束的事件。因此,您有一个循环等待某件事完成,但它正在等待的事情在循环完成之前无法完成 - 僵局。
因此,由于 JS 解释器的单线程事件循环性质,您不能(纯粹在 Javascript 中)阻塞等待异步操作的结束。
几乎总是,正确的设计是重构周围的代码/基础设施以处理异步操作和异步结果(回调或承诺)。
如果这是 Node.js,有一些可怕的黑客可以让你得到这个结果,但它们会阻止整个解释器,所以几乎从来都不是理想的设计。
第一个选项涉及编写一个自定义 Nodejs 插件(在本机代码中完成的异步操作),该插件提供一个阻塞接口,该接口在操作完成之前不会返回。
第二个选项涉及使用同步子进程操作 https://nodejs.org/api/child_process.html#child_process_synchronous_process_creation(例如child_process.execFileSync()
要创建阻塞子进程,请在该子进程中运行代码,然后在该进程完成后继续。
我认为这两者都是非常糟糕的黑客行为,而且几乎从来都不是解决此类问题的理想方法。但是,我确实想向您展示必须做什么才能阻止异步操作(必须将其移出 Javascript 或移出进程)。
如果您无法弄清楚如何通过非阻塞异步操作解决您的实际问题,我建议您发布一个新问题,在其中详细描述真正的问题是什么,我们可以帮助您找到异步设计这适合你的情况。如果您在此处的评论中发布指向新问题的链接,这里参与的一些人可能会检查新问题并尝试提供帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)