JS:为什么 Promise then() 方法同步执行?
JS: Why Promise then() method executes synchronously?
我需要使方法的部分代码异步,以便它以非阻塞方式执行。为此,我尝试创建一个“虚拟”Promise 并将指定的代码放入 then
块中。我有这样的东西:
public static foo(arg1, arg2) {
const prom = new Promise((resolve, reject) => {
if (notValid(arg1, arg2)) {
reject();
}
resolve(true);
});
prom.then(() => {
...my code using arg1 and arg2...
});
}
然而,then
块总是同步执行并阻塞整个应用程序,即使每个 JS 文档都告诉 then
总是 运行 是异步的。我也尝试用这个替换 Promise:
Promise.resolve().then(() => {
...my code using arg1 and arg2...
});
但得到了相同的结果。
我设法使 then
块异步工作的唯一方法是使用 setTimeout
:
const pro = new Promise(resolve => {
setTimeout(resolve, 1);
});
pro.then(() => {
...my code using arg1 and arg2...
})
then
块同步工作背后的原因是什么?我不想继续使用 setTimeout
,因为它是一种“肮脏”的解决方案,我认为应该有一种方法可以使 then
运行 异步。
应用程序是 NodeJS with Express,使用 Typescript 编写。
I need to make part of my method's code asynchronous, so it will execute in a non-blocking manner. For this purpose I've tried to create a "dummy" Promise and put the specified code in then block.
Promise 本身并不能真正使事情异步。他们所做的是包装一些已经异步的东西,并提供一种方便的方式来判断这件事何时完成。如果你围绕同步的东西包装一个承诺,你的代码大部分仍然是同步的,只是有一些关于 .then 回调何时执行的细节。
even though each and every JS documentation tells that then always runs asynchronously.
他们的意思是等待当前调用堆栈完成,然后运行 .then
回调中的代码。它正在做的事情的技术术语是“微任务”。完成此延迟后,无论 promise 是否已处于已解决状态,或者是否需要一段时间才能解决,代码的操作顺序都是相同的。
但是,如果您的承诺已经解决(例如,因为它包裹在同步代码中),您的 .then
回调将唯一等待的是当前正在执行的调用堆栈。一旦当前调用堆栈同步完成,您的微任务就会同步运行直至完成。在您完成之前,事件循环将无法继续。
The only way I've managed to make then block work asynchronously is by using setTimeout
setTimeout 将使事情变得异步*,是的。代码将被延迟,直到计时器关闭。如果你想把它包装在一个承诺中,你可以,但承诺不是使它异步的部分,setTimeout 是。
I don't want to proceed with using setTimeout, because it is kind of a "dirty" solution
好的,但它是完成这项工作的正确工具。
* 当我说 setTimeout 使它异步时,我的意思是它延迟了执行。这在很多情况下已经足够好了,但是当您的代码最终执行时,它会占用线程直到完成。因此,如果需要很长时间,您可能需要编写代码,使其只完成一部分工作,然后设置另一个超时以稍后恢复
我需要使方法的部分代码异步,以便它以非阻塞方式执行。为此,我尝试创建一个“虚拟”Promise 并将指定的代码放入 then
块中。我有这样的东西:
public static foo(arg1, arg2) {
const prom = new Promise((resolve, reject) => {
if (notValid(arg1, arg2)) {
reject();
}
resolve(true);
});
prom.then(() => {
...my code using arg1 and arg2...
});
}
然而,then
块总是同步执行并阻塞整个应用程序,即使每个 JS 文档都告诉 then
总是 运行 是异步的。我也尝试用这个替换 Promise:
Promise.resolve().then(() => {
...my code using arg1 and arg2...
});
但得到了相同的结果。
我设法使 then
块异步工作的唯一方法是使用 setTimeout
:
const pro = new Promise(resolve => {
setTimeout(resolve, 1);
});
pro.then(() => {
...my code using arg1 and arg2...
})
then
块同步工作背后的原因是什么?我不想继续使用 setTimeout
,因为它是一种“肮脏”的解决方案,我认为应该有一种方法可以使 then
运行 异步。
应用程序是 NodeJS with Express,使用 Typescript 编写。
I need to make part of my method's code asynchronous, so it will execute in a non-blocking manner. For this purpose I've tried to create a "dummy" Promise and put the specified code in then block.
Promise 本身并不能真正使事情异步。他们所做的是包装一些已经异步的东西,并提供一种方便的方式来判断这件事何时完成。如果你围绕同步的东西包装一个承诺,你的代码大部分仍然是同步的,只是有一些关于 .then 回调何时执行的细节。
even though each and every JS documentation tells that then always runs asynchronously.
他们的意思是等待当前调用堆栈完成,然后运行 .then
回调中的代码。它正在做的事情的技术术语是“微任务”。完成此延迟后,无论 promise 是否已处于已解决状态,或者是否需要一段时间才能解决,代码的操作顺序都是相同的。
但是,如果您的承诺已经解决(例如,因为它包裹在同步代码中),您的 .then
回调将唯一等待的是当前正在执行的调用堆栈。一旦当前调用堆栈同步完成,您的微任务就会同步运行直至完成。在您完成之前,事件循环将无法继续。
The only way I've managed to make then block work asynchronously is by using setTimeout
setTimeout 将使事情变得异步*,是的。代码将被延迟,直到计时器关闭。如果你想把它包装在一个承诺中,你可以,但承诺不是使它异步的部分,setTimeout 是。
I don't want to proceed with using setTimeout, because it is kind of a "dirty" solution
好的,但它是完成这项工作的正确工具。
* 当我说 setTimeout 使它异步时,我的意思是它延迟了执行。这在很多情况下已经足够好了,但是当您的代码最终执行时,它会占用线程直到完成。因此,如果需要很长时间,您可能需要编写代码,使其只完成一部分工作,然后设置另一个超时以稍后恢复