Promise和async & await一些知识

本文深入探讨Promise的基础用法及状态变化,解释了异步编程中Promise如何通过resolve和reject进行状态转换,并展示了Promise与async/await在JavaScript中的应用。通过代码示例,解析了Promise的回调机制、微任务队列的执行流程以及async函数如何返回Promise对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Promise基础用法

new Promise( function(resolve, reject) {...} /* executor */  )

promise是异步请求时会使用,一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)。在调用时候会传入resolve和reject参数,resolve是状态由pending至fulfilled,即状态成功回调。reject是失败回调。
在这里插入图片描述
Promise 是用来管理异步编程的,它本身不是异步的,new Promise的时候会立即把executor函数执行
代码片段1:

let p1 = new Promise(()=>{
    setTimeout(()=>{
      console.log(1)
    },0)
    console.log(2)
  })
console.log(3) // 2 3 1

上面代码会先执行promise中的回调,打印2,然后继续执行打印3,由于打印1延时处理,属于开启的新任务,会等其他任务执行完成,再执行1。

代码片段2:

let p1 = new Promise((resolve,reject)=>{
  console.log(1);
  resolve('执行promise')
  console.log(2)
})
// then:设置成功或者失败后处理的方法
p1.then(result=>{
 //p1延迟绑定回调函数
  console.log('成功 '+result)
},reason=>{
  console.log('失败 '+reason)
})
console.log(3)
// 1
// 2
// 3
// 成功 执行promise

Promise 采用了回调函数延迟绑定技术,在执行 resolve 函数的时候,回调函数还没有绑定,那么只能推迟回调函数的执行
代码片段2中,先执行打印1,p1中resolve的回调函数还没绑定,会出发微任务,将p1.then暂存起来,继续执行打印2,打印3,同步任务执行完毕后,去执行微任务,执行.then中方法。

代码片段3:

new Promise(resolve=>{
    resolve(a) // 报错 
// 这个executor函数执行发生异常错误,决定下个then失败方法会被执行
}).then(result=>{
    console.log(`成功:${result}`)
    return result*10
},reason=>{
    console.log(`失败:${reason}`)
// 执行这句时候,没有发生异常或者返回一个失败的Promise实例,所以下个then成功方法会被执行
// 这里没有return,最后会返回 undefined
}).then(result=>{
    console.log(`成功:${result}`)
},reason=>{
    console.log(`失败:${reason}`)
})
// 失败:ReferenceError: a is not defined
// 成功:undefined
  • 不论是成功的方法执行,还是失败的方法执行(then中的两个方法),凡是执行抛出了异常,则都会把实例的状态改为失败。
  • 方法中如果返回一个新的Promise实例(比如上例中的Promise.reject(1)),返回这个实例的结果是成功还是失败,也决定了当前实例是成功还是失败。
  • 剩下的情况基本上都是让实例变为成功的状态,上一个then中方法返回的结果会传递到下一个then的方法中

async & await

ES7中新增的异步编程方法,async/await的实现是基于 Promise的,简单而言就是async 函数就是返回Promise对象
1、带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装。

async function test() {
    return 'test'
}
test(); //Promise {<resolved>: "test"}

2、await等待右侧表达式的结果,这个结果是promise对象或者其他值。
遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。以下面的代码分析:

 async function test1() {
            console.log('start test1');
            console.log(await test2());
            console.log('end test1');
        }
        async function test2() {
            console.log('test2');
            return 'return test2 value'
        }
        test1();
        console.log('start async');
        setTimeout(() => {
            console.log('setTimeout');
        }, 0);
        new Promise((resolve, reject) => {
            console.log('promise1');
            resolve();
        }).then(() => {
            console.log('promise2');
        });
        console.log('end async');

执行的结果
在这里插入图片描述

· 首先执行宏任务,执行test1函数,执行console.log(‘statr test1’)

· 遇到await,先执行右边test2中的console.log(‘test2’),test2())执行完成后返回Promise {: “return test2 value”},是promise对象,推到微任务队列中**,执行test1外面的同步代码

· 执行console.log(‘start async’);

· 遇到setTimeout,推到到下个宏任务队列中

· 执行Promise里面的同步代码console.log(‘promise1’)

· 运行到promise().then,发现是promise对象,推到微任务队列中

· 执行console.log(‘end async’)

· **test1外面的同步代码执行结束后,回到test1中,console.log(await

· 此时第一个宏任务结束,执行所有的微任务,因为微任务队列先进先出,所以先执行console.log(‘return test2 value’) ,执行test2完成后,后面的代码不再阻塞,执行console.log(‘end test1’);后执行console.log(‘promise2’)
· 执行下个宏任务,即执行console.log(‘setTimeout’);

补充下有关宏任务和微任务的知识

宏任务和微任务都是队列,宏任务有script、setTimeout、setInterval等,微任务有Promise.then catch finally、process.nextTick等,宏任务和微任务的关系如下:
在这里插入图片描述

先执行第一个宏任务,执行结束后,执行所有的微任务,然后执行下个宏任务。

参考链接:https://www.cnblogs.com/bear-blogs/p/10423759.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值