Promise介绍与基本使用
理解
1.抽象表达
-
Promise是一门新的技术(ES6规范)
-
Promise是JS中进行异步编程的新解决方案
备注:旧方案是单纯使用回调函数
2.具体表达
-
从语法上来说Promise是一个构造函数
-
从功能上来说:Promise对象用来封装一个异步操作并可以获取其成功/失败的结果值
为什么要用Promise?
-
指定回调函数的方式更加灵活
-
旧的:必须在启动异步任务前指定
-
promise:启动异步任务=>返回promie对象=→>给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)
-
-
支持链式调用,可以解决回调地域的问题
1.什么是回调地狱? 回调函数嵌套调用,外部回调函数异步执行的结果是嵌 套的回调执行的条件
2.回调地狱的缺点? 不便于阅读不便于异常处理
3.解决方案? promise链式调用
4.终极解决方案?
抽奖
运行结果
fs模块
const fs = require('fs');
// fs.readFile('./resource/resource.txt', (err, data) => {
// //如果出错,则抛出错误
// if (err) throw err;
// //输出文件内容
// console.log(data.toString());
// })
//Promise
let p = new Promise((resolve, reject) => {
fs.readFile('./resource/resource.txt', (err, data) => {
//如果出错,则抛出错误
if (err) reject(err);
//输出文件内容
resolve(data);
});
});
p.then((value) => {
console.log(value.toString());
}, (reason) => {
console.log(reason)
})
ajax
<!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>Document</title>
</head>
<body>
<button id="btn">请求ajax</button>
<script>
const btn = document.getElementById("btn");
btn.addEventListener("click", function () {
// const xhr = new XMLHttpRequest();
// xhr.open('GET', 'https://api.apiopen.top/getJoke')
// xhr.send();
// xhr.onreadystatechange = function () {
// if (xhr.readyState === 4) {
// //判断响应状态码2xx
// if (xhr.status >= 200 && xhr.status < 300) {
// //控制台输出响应体
// console.log(xhr.response);
// } else {
// console.log(xhr.status)
// }
// }
// }
//Promise
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.apiopen.top/getJoke')
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
//判断响应状态码2xx
if (xhr.status >= 200 && xhr.status < 300) {
//控制台输出响应体
resolve(xhr.response);
} else {
reject(xhr.status)
}
}
}
})
p.then(value => {
console.log(value)
}), reason => {
console.warn(reason)
}
})
</script>
</body>
</html>
封装fs模块
// 封装一个函数 mineReadFile读取文件内容
// 参数:path 文件路径
// 返回:promise对象
function mineReadFile(path) {
return new Promise((resolve, reject) => {
require('fs').readFile(path, (err, data) => {
if (err) reject(err);//成功
resolve(data);
})
});
}
mineReadFile('./resource/resource.txt').then(value => {
console.log(value.toString());
}, reason => {
console.log(reason);
});
util.promisify方法
// util.promisify方法
//引入utilmokuai
const util = require('util');
//引入fs模块
const fs = require('fs')
//返回一个新的函数
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./resource/resource.txt').then(value => {
console.log(value.toString())
})
sendAjax
promise的状态改变
-
pending变为resolved
-
pending 变为rejected 说明:只有这2种,且一个promise对象只能改变一次 无论变为成功还是失败,都会有一个结果数据成功的结果数据一般称为value,失败的结果数据一般称为reason
实例对象中的一个属性PromiseState
pending 未决定的
resolve/fullfilled 成功
rejected 失败
Promise对象的值
实例对象中的另一个属性 PromiseResult
保存着异步任务对象[成功/失败]的结果
只有resolve/reject可以修改
promise的工作流程
如何使用Promise
API
-
Promise构造函数:Promise (excutor){} (1) executor函数:执行器(resolve, reject)=>{}
(2)resolve函数:内部定义成功时我们调用的函数value =>{}
(3) reject函数:内部定义失败时我们调用的函数reason =>{} 说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行,也就是这个函数不会进入到队列当中去
-
Promise.prototype.then方法:(onResolved, onRejected) =>{}(1)onResolved,函数:成功的回调函数(value)=>{} (2)onRejected函数:失败的回调函数(reason) =>{} 说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调返回一个新的promise对象
-
Promise.prototype.catch方法: (onRejected) => {} (1) onRejected函数:失败的回调函数(reason) => {}
-
Promise.resolve方法: (value)=> {} (1) value: 成功的数据或promise对象 说明:返回一个成功/失败的promise对象
-
Promise.reject方法: (reason) => {} (1) reason: 失败的原因. 说明:返回一个失败的promise对象
-
Promise.all方法: (promises)=> {} (1) promises: 包含n个promise的数组 说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一-个失败了就直接失败
-
Promise.race 方法: (promises)=> {} : (1) promises: 包含n个promise的数组 说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
promise的几个关键问题
-
如何改变promise的状态? (1) resolve(value): 如果当前是pending就会变为resolved (2) reject(reason): 如果当前是pending就会变为rejected (3) 抛出异常:如果当前是pending就会变为rejected throw ’出错啦!‘
-
一个promise指定多个成功/失败回调函数,都会调用吗? 当promise改变为对应状态时都会调用
-
改变promise状态和指定回调函数谁先谁后? (1)都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
①如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
②如果先改变状态,那当指定回调时,回调函数就会调用,得到数据
-
promise.then()返回的新promise的结果状态由什么决定? (1)简单表达: 由then()指定的回调函数执行的结果决定 (2)详细表达: ①如果抛出异常, 新promise变为rejected, reason为抛出的异常 ②如果返 回的是非promise的任意值,新promise变为resolved, value为返回的值
浙公网安备 33010602011771号