FrontEnd笔记 -- Promise

一、介绍

  • 是什么
  1. Promise 是 JS 中进行异步编程的新解决方案;
  2. 从语法上来说:Promise 是一个构造函数;
  3. 从功能上来说:Promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值。
  • 优点
  1. 指定回调函数的方式更加灵活:旧的异步任务必须在其启动前指定,而 Promise 是启动异步任务 => 返回 promise 对象 => 给 promise 对象绑定回调函数(可以指定多个)
  2. 支持链式调用,解决回调地狱(回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件)的问题。

在这里插入图片描述

1.1 初体验

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <h2 class="page-header">Promise 初体验</h2>
    <button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
</body>
<script type="text/javascript">
    function rand(m, n) {
        return Math.ceil(Math.random() * (n-m+1)) + m-1
    }

    const btn = document.querySelector('#btn');
    btn.addEventListener('click', function(){
        const n = rand(1,100)
        //定时器方式
        // setTimeout(() => n<=30 ? alert('恭喜中奖') : alert('再接再厉'), 1000)

        //Promise 形式实现
        // resolve 成功回调函数
        // reject  失败回调函数
        const p = new Promise((resolve, reject)=>
                                setTimeout(()=> n<=30 ? resolve(n) : reject(n), 1000))
        //p.then(resolve(), reject())
        // value  结果值
        // reason 失败原因
        p.then(value=>alert('恭喜中奖,号码:'+value), reason=>alert('再接再厉,号码:'+reason))

    })
</script>
</html>

在这里插入图片描述

  • Promise 调用流程

在这里插入图片描述

  1. pending:悬而未决的
  2. resolved:成功的
  3. rejected:失败的

1.2 Promise函数

  • Promise 基本函数

executor会在 Promise内部立即同步调用 ,异步操作在执行器中执行。

  1. executor函数 : 执行器 (resolve, reject) => {}
  2. resolve函数 : 内部定义成功时我们调用的函数 value => {}
  3. reject函数 : 内部定义失败时我们调用的函数 reason => {}
  4. then函数:Promise.prototype.then(onResolved, onRejected) => {}
  5. catch函数:Promise.prototype.catch(onRejected) => {}
new Promise((resolve,reject)=>{
   // if(success-condition) resolve(value/result)
   // if(failed-condition)  reject(reason)
}).then(value=>{
   // do something with(value)
}).catch(reason=>{
   // react with cause(reason)
})
  • Promise.resolve(value) => {}

返回一个成功 /失败的 promise对象

  1. value: 成功的数据或 promise对象;
  2. 如果传入的参数为非Promise类型的对象,则返回的结果是成功的Promise对象;
  3. 如果传入的参数为Promise类型的对象,则参数的结果结果决定了返回的Promise对象结果。
  • Promise.reject(reason) => {}

返回一个失败的 promise对象

  1. reason: 失败的原因
  2. 如果传入的参数为非Promise类型的对象,则返回的结果是失败的Promise对象;
  3. 如果传入的参数为Promise类型的对象,仍返回的结果是失败的Promise对象,返回的Promise结果是传入的Promise对象。
const p1 = Promise.resolve("Success")
const p2 = Promise.resolve(new Promise((resolve,reject)=>{
  // if(success-condition) resolve(value/result) -- p2 is fufilled
  // if(failed-condition)  reject(reason) -- p2 is rejected
}))

const p3 = Promise.reject("Failed")
const p4 = Promise.resolve(new Promise((resolve,reject)=>{
  // if(success-condition) resolve(value/result) -- p4 is rejected
  // if(failed-condition)  reject(reason) -- p4 is rejected
}))
  • Promise.all((promises) => {})

返回一个新的 promise, 只有所有的 promise都成功才成功 , 只要有一个失败了就直接失败。

  1. promises: 包含 n个 promise的数组
  • Promise.race(promises) => {}

返回一个新的 promise, 第一个完成的 promise的结果状态就是最终的结果状态。

  1. promises: 包含 n个 promise的数组
const p1 = Promise.resolve("Success")
const p2 = Promise.resolve("Done")
const p3 = new Promise((resolve,reject)=>{
   // if(success-condition) resolve(value/result)   -- allResult is resolved
   // if(failed-condition)  reject(reason)  -- allResult is rejected
})

const allResult  = Promise.all([p1,p2,p3])
const raceResult = Promise.race([p1,p2,p3])

1.3 封装 Ajax 请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise 封装 AJAX</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <h2 class="page-header">Promise 封装 AJAX 操作</h2>
        <button class="btn btn-primary" id="btn">点击发送 AJAX</button>
    </div>
</body>
<script>
    //封装Ajax请求
    function sendAjax(url) {
        return new Promise((resolve, reject)=>{
            //1.创建对象
            const xhr = new XMLHttpRequest()
            //2.初始化
            xhr.open('GET', url)
            //3.发送
            xhr.send()
            //4.处理响应结果
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4)
                    xhr.status >= 200 && xhr.status < 300 ? resolve(xhr.response) : reject(xhr.status)
            }
        })
    }

    //点击按钮调用Ajax
    const btn = document.querySelector('#btn')
    const url = 'https://api.apiopen.top/getJoke'
    btn.addEventListener('click', ()=>sendAjax(url).
                                      then(value=>console.log(value)).
                                      catch(reason=>console.error(reason)))
</script>
</html>

1.4 async 和 await

  • async 函数
  1. 函数的返回值为promise 对象
  2. promise 对象的结果由async 函数执行的返回值决定
  • await 表达式

await 必须写在async 函数中, 但async 函数中可以没有await

  1. await 右侧的表达式一般为promise 对象, 但也可以是其它的值
  2. 如果表达式是promise 对象, await 返回的是promise 成功的值
  3. 如果await 的promise 失败了, 就会抛出异常, 需要通过try…catch 捕获处理
  4. 如果表达式是其它值, 直接将此值作为await 的返回值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise 封装 AJAX</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <h2 class="page-header">Promise 封装 AJAX 操作</h2>
        <button class="btn btn-primary" id="btn">点击发送 AJAX</button>
    </div>
</body>
<script>
	//封装Ajax请求
    function sendAjax(url) {
        return new Promise((resolve, reject)=>{
            const xhr = new XMLHttpRequest()
            xhr.open('GET', url)
            xhr.send()
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4)
                    xhr.status >= 200 && xhr.status < 300 ? resolve(xhr.response) : reject(xhr.status)
            }
        })
    }

	//1. 需要拼接多个异步请求的处理结果时
    const btn  = document.querySelector('#btn')
    const url1 = 'https://api.apiopen.top/getJoke'
    const url2 = 'https://api.apiopen.top/getJoke'
    const url3 = 'https://api.apiopen.top/getJoke'

    //2. async + await 组合使用,解决回调地狱问题,且比链式调用更优美。
    btn.addEventListener('click', async function(){
    	try {
    		let result1 = await sendAjax(url1)
	    	let result2 = await sendAjax(url2)
	    	let result3 = await sendAjax(url3)
	    	console.log(result1 + result2 + result3)
    	}catch(e){
    		console.error(e)
    	}
    })
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值