【问题标题】:Which part of the Javascript Promise function is asynchronous?Javascript Promise 函数的哪一部分是异步的?
【发布时间】:2021-10-03 22:20:36
【问题描述】:

我正在学习 Javascript 异步编程和 Promise。我有以下代码。

let promiseTest = () => new Promise((resolve, reject) => {
console.log("Inside Promise");
resolve('Promise is resolved'); 
});

console.log("Before Promise"); 
promiseTest().then((data) => { console.log(data); });
console.log("After Promise");

我有函数“promiseTest”。我想异步执行。在现实世界的场景中,它可能是一个获取 Web 服务或查询数据库的函数。我期望从代码中得到以下结果。

Before Promise
After Promise
Inside Promise
Promise is resolved

我期待“console.log(" Inside Promise") ”将异步执行,因为它位于 Promise 函数中。但实际结果是

Before Promise
Inside Promise
After Promise
Promise is resolved

正如你看到的实际结果,Inside Promise 是同步执行的,并且阻塞了主线程。只有“resolve”中的代码是异步的。也许,我目前对 javascript Promise 的理解是不正确的。如何修改现有代码以确保整个函数“promiseTest”异步执行而不会阻塞主线程。

【问题讨论】:

  • 注意,即使是延迟的部分也会阻塞主线程。不阻塞主线程的唯一方法是使用其他线程。

标签: javascript asynchronous es6-promise


【解决方案1】:

executor函数是同步执行的。 Promise 不会使任何代码异步;它只是一种在已经异步的事情完成时收到通知的机制。

如果您想进行 API 调用,这已经是异步的,并且如果您使用 fetch API,那么您不需要 promise 构造函数,因为fetch(...) 已经返回了一个 promise。

只有“resolve”里面的代码是异步的

在您的代码中,resolve() 函数也被同步调用;只有promiseTest().then(..)的回调函数被异步调用。

如何修改我现有的代码以确保整个功能 "promiseTest" 异步执行,不阻塞 main 线程。

您将不得不使用另一个thread。即使你使用setTimeout延迟了promiseTest函数的执行,一旦它被压入调用堆栈,它也会同步执行。执行延迟的promiseTest 函数时不会执行任何其他操作。

如果您想要延迟执行,只需将promiseTest 函数调用包装在setTimeout 中。

【讨论】:

  • 感谢您的解释。因此,promise 不会使函数异步。该 promise 函数内部会有异步调用,promise 提供的是在这些异步调用完成后通知调用者(使用 resolve、reject )的机制。我对你的理解正确吗?
  • 是的,没错。 Promise 是已经异步操作的包装器。
【解决方案2】:

我建议将setTimeout 用于您的 promiseTest 函数,这将为您提供预期的结果。

setTimeout 设置了一个定时器,一旦定时器到期就执行一个函数。

正如您所见,“承诺后”将在“承诺已解决”之前记录,这是完全可以预料的,因为承诺需要一些时间(在本例中为 1000 毫秒)才能解决。

let promiseTest = () => new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("Inside Promise"); 
        resolve('Promise is resolved');
    }, 1000) 
});

console.log("Before Promise"); 
promiseTest().then((data) => { console.log(data); });
console.log("After Promise");

【讨论】:

  • 他们希望“Inside Promise”稍后执行,这里的结果与他们大致相同,只是在调用 then 回调之前发生了完整的事件循环。
  • 感谢您的解决方案。我刚刚注意到一个技巧,我可以将整个块代码放入 setTimeout 中,以便稍后执行一个函数。
猜你喜欢
  • 2016-08-03
  • 2019-10-23
  • 2018-04-19
  • 1970-01-01
  • 2021-02-15
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
相关资源
最近更新 更多