异步承诺返回函数的同步与异步执行 [英] Synchronous vs asynchronous execution of an asynchronous promise returning function

查看:79
本文介绍了异步承诺返回函数的同步与异步执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在制作返回 promise 的异步函数时,我在每个实现中都看到过这种做法:

When making asynchronous functions that return promises, in every implementation i've seen this practice:

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

也就是说,executor函数中的函数代码是同步运行的,只有promise settling和callback调用是异步完成的.这对我来说是违反直觉的,因为当我想到异步函数时,我会想到一个函数,当它执行时,立即返回,并将其操作推迟到以后.下面是一个例子:

In other words, the function code in the executor function is run synchronously, and only promise settling and and callback calling is done asynchronously. This has been counter-intuitive to me, because when I think of an asynchronous function, I think of a function that when it executes, returns immediately, and defers it's operations for later. Here is an example:

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

这意味着该函数的代码将在一个任务中执行,并且所有在返回的 Promise 上注册的回调都将作为微任务运行.该函数立即返回,并且不会使线程挨饿.

This means that the code of the function will execute in a task, and all the callbacks registered on the returned promise will run as microtasks. The function returns immediately, and doesn't starve the thread.

我现在有几个问题.

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

推荐答案

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

Promises are tools to manage asynchronous code, not to make code asynchronous.

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

Your first example shouldn't use promises at all. Everything the function does is blocking. The use of a promise only adds complication. (The exception is if you are writing code to match an interface which is sometimes used for something asynchronous).

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

Your second example is also pointless (at least almost always). The timeout is being added just to let the event loop continue with something outside the function before picking it up again later. This can be useful (e.g. to allow the browser to repaint the window before doing something time consuming) but the approach should be:

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

...而您的代码似乎正在扭转这种局面,并从承诺开始并试图证明其使用的合理性.

… whereas your code seems to be turning that upside and starting with a promise and trying to justify its use.

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

If you have some time-consuming code to run and you don't want it to block the main event loop then you should probably be using a worker so it runs on a different thread. Possibly you would use a Promise to handle that code sending its result back to the main event loop.

这篇关于异步承诺返回函数的同步与异步执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆