promise、async、await学习

本文详细介绍了Promise的基本概念、使用方式、为什么使用Promise、如何使用Promise,以及如何自定义Promise。接着,讨论了async函数和await表达式的用法,强调了它们在解决异步编程问题上的优势。通过实例展示了Promise、async和await在实际操作中的应用,包括文件读取、AJAX请求和解决回调地狱问题。
摘要由CSDN通过智能技术生成


前言

此为学习笔记整理,具体参考b站尚硅谷学习视频。


一、Promise 的理解和使用

1、Promise 是什么?

(1)理解

①抽象表达:

  1. Promise 是一门新的技术(ES6 规范)
  2. Promise 是 JS 中进行异步编程的新解决方案(旧方案是单纯使用回调函数)

②具体表达:
1)它通过引入一个回调,避免更多的回调,简单说Promise就是一个容器,里面保存着某个未来才会结束的事件 (通常是一个异步操作)的结果。
2) 从语法上来说: Promise 是一个构造函数
3) 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

那么,我们在学习中一般会遇到哪些异步编程问题呢:
①fs 文件操作

require('fs').readFile('./index.html', (err,data)=>{
   })

②数据库操作
③AJAX

$.get('/server', (data)=>{
   })

④定时器

setTimeout(()=>{
   }, 2000);

(2)promise 的状态改变

Promise的状态其实就是实例对象中的一个属性【PromiseState】,有三种可能值pending未决定的、resolved(fullfilled)成功、rejected失败
①pending 变为 resolved
②pending 变为 rejected
说明: 只有这 2 种, 且一个 promise 对象只能改变一次,无论变为成功还是失败, 都会有一个结果数据,成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

(3)Promise对象的值

实例对象中的另一个属性【PromiseResult】,保存着异步任务【成功/失败】的结果。
只有resolve与reject这两个函数才可以修改这个值

(4)promise 的基本流程

在这里插入图片描述
注意:

Promise 状态发生改变,就会触发.then()里的响应函数处理后续步骤.。
Promise 状态一经改变,不会再变。
Promise实例一经创建,执行器立即执行。

(5)promise 的基本使用

①基本编码流程
<script>
	// 1) 创建 promise 对象(pending 状态), 指定执行器函数
	const p = new Promise((resolve, reject) => {
   
		// 2) 在执行器函数中启动异步任务
		setTimeout(() => {
   
			const time = Date.now()
			// 3) 根据结果做不同处理
			// 3.1) 如果成功了, 调用 resolve(), 指定成功的 value, 变为 resolved 状 态
			if (time%2===1) {
   
				resolve('成功的值 '+ time) 
				} else {
    // 3.2) 如果失败了, 调用 reject(), 指定失败的 reason, 变为rejected 状态
					reject('失败的值' + time) 
				}
		}, 2000)
	})
	// 4) 能 promise 指定成功或失败的回调函数来获取成功的 vlaue 或失败的 reason
	p.then(
		value => {
    // 成功的回调函数 onResolved, 得到成功的 vlaue
			console.log('成功的 value: ', value)
		},
		reason => {
    // 失败的回调函数 onRejected, 得到失败的 reason
			console.log('失败的 reason: ', reason)
		} 
	)
</script>
②使用 promise 封装基于定时器的异步
<script>
	function doDelay(time) {
   
		// 1. 创建 promise 对象
		return new Promise((resolve, reject) => {
   
			// 2. 启动异步任务
			console.log('启动异步任务')
			setTimeout(() => {
   
				console.log('延迟任务开始执行...')
				const time = Date.now() // 假设: 时间为奇数代表成功, 为偶数代表失败
				if (time %2=== 1) {
    // 成功了
					// 3. 1. 如果成功了, 调用 resolve()并传入成功的 value
					resolve('成功的数据 ' + time) 
				} else {
    // 失败了
					// 3.2. 如果失败了, 调用 reject()并传入失败的 reason
					reject('失败的数据 ' + time) }
				}, time)
		})
	}
	const promise = doDelay(2000)
	promise.then(
		value => {
   
			console.log('成功的 value: ', value)
		},
		reason => {
   
			console.log('失败的 reason: ', reason)
		},
	)
</script>
③使用 promise 封装 ajax 异步请求
<script>
	/*
	可复用的发 ajax 请求的函数: xhr + promise
	*/
	function promiseAjax(url) {
   
		return new Promise((resolve, reject) => {
   
			const xhr = new XMLHttpRequest()
			xhr.onreadystatechange = () => {
   
				if (xhr.readyState!==4) return
				const {
   status, response} = xhr
				// 请求成功, 调用 resolve(value)
				if (status>=200 && status<300) {
   
					resolve(JSON.parse(response))
				} else {
    // 请求失败, 调用 reject(reason)
					reject(new Error('请求失败: status: ' + status))
				} 
			}
			xhr.open("GET", url)
			xhr.send()
		})
	}
	promiseAjax('https://api.apiopen.top2/getJoke?page=1&count=2&type=video')
		.then(
			data => {
   
				console.log('显示成功数据', data)
			},
			error => {
   
				alert(error.message) 
			} 
		)
</script>
④案例1-promise初体验

      现在我们有如下要求,用户点击抽奖按钮后,两秒之后显示是否中奖(30%概率),若中奖则弹出“恭喜恭喜,奖品为小熊笔记本一个,您的中奖数字为?”,若未中奖,则弹出“再接再厉,您的号码为?”。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>抽奖</title>
</head>
<body>
    <div class="container">
        <button class="btn btn-primary" id="btn">点击抽奖</button>
    </div>
    <script>
        //生成随机数
        function rand(m,n){
   
            return Math.ceil(Math.random() * (n-m+1)) + m-1
        }
        //获取元素对象
        const btn = document.querySelector('#btn')
        //绑定单击事件
        btn.addEventListener('click',()=>{
   
            //普通方法
            //定时器
            // setTimeout(()=>{
   
            //     //30%中奖率,即可以获取1-100的一个随机数,如果小于等于30,则中奖
            //     let n = rand(1,100);
            //     //判断
            //     if(n<=30){
   
            //         alert('恭喜恭喜,奖品为小熊笔记本一个')
            //     }else{
   
            //         alert('再接再厉')
            //     }
            // },2000)

            //Promise形式实现
            const p = new Promise((resolve,reject)=>{
   
                //定时器
                setTimeout(()=>{
   
                    //30%中奖率,即可以获取1-100的一个随机数,如果小于等于30,则中奖
                    let n = rand(1,100);
                    //判断
                    if(n<=30){
   
                        resolve(n);//将promise对象的状态设置为【成功】
                    }else{
   
                        reject(n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值