繁体   English   中英

异步 promise 返回 function 的同步与异步执行

[英]Synchronous vs asynchronous execution of an asynchronous promise returning function

在创建返回承诺的异步函数时,在每个实现中我都看到了这种做法:

function asyncFunction() {
 return new Promise((resolve,reject) => {
  // the function code
  if (condition) resolve()
  else reject()
 })
}

也就是说,执行器 function 中的 function 代码是同步运行的,只有 promise 的设置和回调调用是异步完成的。 这对我来说是违反直觉的,因为当我想到异步 function 时,我想到的是 function,它在执行时立即返回,并将其操作推迟到以后。 这是一个例子:

function asyncFunction() {
 return new Promise((resolve,reject) => {
  setTimeout(() => {
   // the function code
   if (condition) resolve()
   else reject()
  }, 0)
  
 })
}

这意味着 function 的代码将在一个任务中执行,并且在返回的 promise 上注册的所有回调将作为微任务运行。 function 立即返回,不会饿死线程。

我现在有几个问题。

  1. 我的推理是否正确/有意义,或者我没有看到一些边缘情况?
  2. 异步 function 的特点是什么? 我看到两个表征异步 function 的候选参数:1. 立即返回并稍后运行其计算,以及 2. 回调稍后/异步运行。 对我来说,唯一具有 function 特征的特征是第一点,但正如我在我能找到的所有代码中看到的那样,唯一重要的是回调是异步运行的。
  3. 使用我的代码版本而不是第一个版本有什么优点/缺点吗?

Promise 是管理异步代码的工具,而不是使代码异步的工具。

您的第一个示例根本不应该使用承诺。 function 所做的一切都是阻塞的。 使用 promise 只会增加复杂性。 (例外情况是,如果您正在编写代码以匹配有时用于异步的接口)。

您的第二个示例也毫无意义(至少几乎总是如此)。 添加超时只是为了让事件循环继续处理 function 之外的内容,然后再将其重新拾取。 可能很有用(例如,允许浏览器在做一些耗时的事情之前重新绘制 window),但方法应该是:

  1. 我需要让 window 在下一个操作运行之前重新绘制
  2. 我将在该操作之前运行超时
  3. 我将使用 Promise 来管理该代码

…而您的代码似乎正在扭转这种局面,并从 promise 开始并试图证明其使用是合理的。

如果您有一些耗时的代码要运行并且您不希望它阻塞主事件循环,那么您可能应该使用工作程序,以便它在不同的线程上运行。 您可能会使用 Promise 来处理将其结果发送回主事件循环的代码。

我想总结一下我从@Bergi 和@Quentin 的回答和评论中学到的东西。 我现在的理解如下:

异步 function 的特点仅在于它立即返回(可能执行或不执行一些同步操作,这无关紧要),最重要的是它以非阻塞方式等待返回一个用于通知其订阅者的值等待结果准备好时收到通知。 此外,function 执行的操作可能会通过以下方式执行:

  1. 线程阻塞,即在我提供的示例中
  2. 非阻塞,并发执行(网络内容,文件读取)
  3. 非阻塞,推迟到以后,例如在我的第二个示例中通过setTimeout

所有三个示例:

第一的:

/**
  Compute the result synchronously, return immediately, and resolve with a value later, calling the callback
*/
function first(cb) {
 // synchronous code
 value = 0;
 setTimeout(() => cb(value), 0) 
} 

这也是另一个例子:

/*
Immediately resolve the promise synchronously, and then call the callback with value
*/
function first(){
 const value = 0;
 return Promise.resolve(value);
}

first().then((value) => {})

第二:

function second() {
  return Promise.resolve(
    fetch('some url'))
    .then(response => response.json())
}

第三:

/*
 Return immediately, perform the function code later, and resolve with a value later
*/
function third() {
 return new Promise((resolve,reject) => {
  setTimeout(() => {
   // the function code
   if (condition) resolve()
   else reject()
  }, 0)
  
 })

主要功能,全部立即返回,将结果传递给回调或以非阻塞方式解析。

随时纠正我,我尽量理解它。 谢谢你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM