JavaScript现代异步方案——Promise、async / await


Promise

⭐ promise是什么?

Promise 对象是一个代理对象,通俗点讲可以把它理解为一个容器。它的参数是个回调函数,该回调接收一个resolvereject函数,异步任务成功的结果绑定至resolve函数,失败的结果绑定至reject函数。

Promise状态

一个 Promise 对象具备三种状态

  • pending: Promise新创建时的初始状态,还未执行 reslove 和 reject 方法
	const pending_promise = new Promise((resolve, reject) => {
    })
    console.log(pending_promise)

在这里插入图片描述

  • resolved/fulfilled: Promise对象在回调函数中调用了resolve方法后的状态
    const resolve_promise = new Promise((resolve, reject) => {
      resolve('resolve_promise')
    })
    console.log(resolve_promise)

在这里插入图片描述

  • rejected: Promise对象在回调函数中调用了reject 方法后的状态
    const reject_promise = new Promise((resolve, reject) => {
      reject('reject_promise')
    })
    console.log(reject_promise)

在这里插入图片描述

Promise状态转换是不可逆的,一旦从pending 状态转换至resolved/rejected,就不能再回到pending状态。

Promise使用——then、catch

Promise就是一个容器,将异步任务包裹在这个容器里即可,异步任务成功和失败的结果分别赋给给 resolve 函数和 reject函数

  • promise读取图像
        function loadImg(url) {
            return new Promise((resolve, reject) => {
                const img = document.createElement('img') 
                img.onload = () => {                     
                    resolve(img)
                }
                img.onerror = () => {
                    const err = new Error(`图片加载失败${url}`)
                    reject(err)
                }
                img.src = url
            })
        }
        // 正确的图片地址
		const url1 = 'https://profile.csdnimg.cn/4/8/2/3_qq_37987033'
		// 错误的图片地址
        const url2 = 'https://profile.csdnimgxx.cn/4/8/2/3_qq_37987033-error' 
  • then、catch方法捕获

使用 promise 的 then 方法能够获取状态为 resolved 时的对象,并进行后续处理。then方法接收的是一个函数,该函数参数为promise执行 resolve 时带过来的值,如果传入的是其它的东西,then方法不会触发。

	loadImg(url1).then(img => {
         console.log(img)               
    })

在这里插入图片描述

使用 promise 的 catch 方法能够获取状态为 rejected 时的错误并抛出

        loadImg(url2).catch((err) => {
            console.error(err)    
        })

在这里插入图片描述

  • 链式调用

promise在使用时允许链式调用

  • 当前一个 promise 的状态为 resolved 时,会跳过 catch 进入下一个 then 方法;当前一个promise的状态为 rejected 时,会跳过 then 进入下一个 catch 方法
  • 在使用链式调用时,then 方法中需要一个返回值作为下个 then 的输入,该返回值会自动被包裹成为一个promise对象,因为只有promise 才有 ············then、catch方法。
  • 无论是then方法还是catch方法,只要它们执行正常,返回值都会变成 resolved 状态;若执行过程中出错,就会变成 rejected 状态
        loadImg(url1).then((img1) => {
            console.log(img1.width, 1)
            return img1              
        }).then(img1 => {
            console.log(img1.height, 2)
            return loadImg(url2)  
        }).then(img2 => {
            console.log(img2, 3)
            return img2
        }).catch(err => {
            console.error(err)
        })

在这里插入图片描述

Promise的异步时机

promise在 new 时就会执行同步方法, resolve包裹而成的 Promise 对象在执行 then 时才是异步的。

        const promise = new Promise((resolve, reject) => {
            console.log(1);
            resolve('resolve1');
            console.log(2);
            resolve('resolve2')  // 状态只能改变一次
            console.log(3);
        });

        // 异步
        promise.then((res) => {
            console.log(4,res); 
        });

        console.log(5);

在这里插入图片描述

Promise其它方法——all、race

  • all

Promise.all 接收一个Promise对象数组

  • 对象数组里所有的 promise 对象都成功的时候才会触发成功
  • 对象数组里只要有一个 promise 失败就会立即触发该 promise 。
	// 成功的promise
    const promise1 = new Promise((resolve, reject) => {
      resolve('promise1')
    })
	// 成功的promise
    const promise2 = new Promise((resolve, reject) => {
      resolve('promise2')
    })
	// 失败的promise
    const promise3 = new Promise((resolve, reject) => {
      reject('promise3')
    })
	// promise.all 全部成功
    Promise.all([promise1, promise2]).then(res => {
      console.log(res);
    });
	// promise.all promise3失败成功
    Promise.all([promise1, promise2, promise3]).then(res => {
      console.log(res);
    }).catch(err=>{
      console.error(err)
    })

在这里插入图片描述

  • race

Promise.race 接收一个Promise对象数组

  • race方法返回第一个执行完毕的 promise 的结果,该结果可以被t hen 或者 catch捕获。
    const promise1 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, 'promise1'); 
    })

    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 50, 'promise2'); 
    })

    const promise3 = new Promise((resolve, reject) => {
      setTimeout(reject, 30, 'promise3'); 
    })

    Promise.race([promise1, promise2]).then(res => {
      console.log(res);
    }).catch(err => {
      console.error(err)
    });

    Promise.race([promise1, promise2, promise3]).then(res => {
      console.log(res);
    }).catch(err => {
      console.error(err)
    });

在这里插入图片描述
先返回 promise3(rejected)是因为定时器执行较早。

async、await

async / await 和Promise的关系

  • ⭐ await需要被一个async函数包裹,后面跟一个promise对象,它们的存在消灭了异步回调
  • 执行 async 函数,返回的是 Promise 对象,如果不是,它会自动把返回值包裹成一个promise对象
  • await 相当于 Promise 的 then;await后面可以跟:1Promise对象;2 普通值(会包裹成Promise.resolve(xx));3 async函数的执行结果
  • try...catch 可以捕获异常,代替了Promise 的 catch

async / await 本身是Promise的语法糖,它让原本的链式调用变成了真正的同步写法。除此之外,async / await 可以使用 try/catch 捕获异常,这是它的一大优势。

async / await 使用

  • async/await 读取图像
        function loadImg(url) {
            return new Promise((resolve, reject) => {
                const img = document.createElement('img') 
                img.onload = () => {                     
                    resolve(img)
                }
                img.onerror = () => {
                    const err = new Error(`图片加载失败${url}`)
                    reject(err)
                }
                img.src = url
            })
        }
        // 正确的图片地址
		const url1 = 'https://profile.csdnimg.cn/4/8/2/3_qq_37987033'
		// 错误的图片地址
        const url2 = 'https://profile.csdnimgxx.cn/4/8/2/3_qq_37987033-error' 

		 async function readImg() {
            try {
                const img1 = await loadImg(url1)  
                console.log(img1.width, img1.height)
                const img2 = await loadImg(url2)
                console.log(img2.width, img2.height)
            } catch (error) {
                console.log(error)
            }
        }
        readImg()

输出如下👇
在这里插入图片描述

总结

Promise

  • Promise状态
  • Promise使用——then、catch
  • Promise的异步时机
  • Promise其它方法——all、race

async、await

  • async / await 和Promise的关系
  • async / await 使用
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值