首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

async/await、promise 和setTimeout工作原理和执行顺序

async/await、Promise和setTimeout在 JavaScript 中都是处理异步操作的方法,但它们的工作原理和执行顺序有所不同。以下是它们的执行顺序和关系的简要说明:

同步代码执行:在任何异步操作开始之前,首先会执行所有的同步代码。

setTimeout:setTimeout设置的回调函数会被放入 JavaScript 的事件队列中,等待当前同步代码执行完毕后才会执行。即使setTimeout的延迟设置为 0,它的回调函数也不会立即执行,而是会在同步代码执行完后,等待事件队列空闲时才会执行。

Promise:Promise对象表示一个异步操作的最终完成(或失败)及其结果值。Promise的执行顺序依赖于其状态。如果Promise已经处于fulfilled或rejected状态,那么其.then()或.catch()中的回调函数会立即执行。如果Promise还在pending状态,那么它的回调函数会被放入微任务队列中,等待当前同步代码和事件队列中的任务执行完毕后才会执行。

async/await:async函数总是返回一个Promise对象。await关键字用于等待一个Promise的解决或拒绝,并返回Promise的解决值。async/await的执行顺序也依赖于Promise。async函数内部的代码会同步执行,直到遇到await关键字。在await关键字处,async函数的执行会暂停,并等待Promise的解决。一旦Promise解决,async函数的执行会恢复,并继续执行后面的代码。由于async/await的执行是基于Promise的,因此它们通常会被放入微任务队列中,与Promise的回调函数一起执行。

在 JavaScript 中,async/await、promise 和setTimeout的执行顺序如下:

1. 当遇到async函数时,会返回一个promise对象,而不会立即执行其内部代码。当async函数中有await时,会暂停函数的执行,等待await后面的表达式的promise对象完成(要么resolved,要么rejected)。await后面的表达式的promise对象完成后,会根据其状态决定下一步的操作。如果是resolved状态,则将其返回值作为await表达式的结果;如果是rejected状态,则抛出错误。

2. 当遇到Promise对象时,会立即执行其内部代码。Promise的then方法也会被封装成微任务,等待当前宏任务执行完毕后执行。

3. 当遇到setTimeout时,会将回调函数放入不同的等待队列,优先级低于await和promise。当定时器到期后,回调函数会被加入到宏任务队列中等待执行。

根据以上执行顺序,在async/await、promise和setTimeout共存的情况下,微任务优先于宏任务执行。下面是一个代码示例:

// 定义一个 async 函数 async1,在其中使用 await 等待 async2 函数执行完成

async function async1() { console.log('async1 start'); await async2(); console.log('async1 end');}

// 定义一个 async 函数 async2async function async2() { console.log('async2');}

// 定义一个 Promise 对象console.log('script start');

setTimeout(() => { console.log('setTimeOut');}, 0);

async1();

new Promise(function (resolve) { console.log('promise1'); resolve();}).then(function () { console.log('promise2');});console.log('script end');

上面代码执行打印顺序:

script startasync1 start async2 promise1script end promise2 async1 endsetTimeOut

上面代码执行顺序说明

1、执行console.log('script start'),输出script start;

2、执行setTimeout,是一个异步动作,放入宏任务异步队列中;

3、执行async1(),输出async1 start,继续向下执行;

4、执行async2(),输出async2,并返回了一个promise对象,await让出了线程,把返回的promise加入了微任务异步队列,所以async1()下面的代码也要等待上面完成后继续执行;

5、执行 new Promise,输出promise1,然后将resolve放入微任务异步队列;

6、执行console.log('script end'),输出script end;

7、到此同步的代码就都执行完成了,然后去微任务异步队列里去获取任务

8、然后执行resolve(new Promise的),输出了promise2。

9、接下来执行resolve(async2返回的promise返回的),输出了async1 end。

10、最后执行setTimeout,输出了settimeout。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OfoVm0CV8bIc6dMwMRHHoNTw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券