概述: Promise (期约)是 ES6 引入的异步编程的新解决方案。
一、promise对象:代表了将来某个将要发生的事件(通常是异步操作),可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数
二、语法上 Promise 是一个构造函数用来生成promise实例 :
参数函数resolve的参数可以是另一个promise,此时当前promise会等待另一个promise状态发生改变时才继续执行
promise共有三个状态:
pendding 初始化状态
fullfilled 成功状态
rejected 失败状态
Promise封装ajax代码示例:
let url = ''
function getNews(url){
let xmlRequest = new XMLHttpRequest(url)
// 1. 创建promise的实例
let promise = new Promise((resolve, reject)=>{
// promise处于初始化状态
xmlRequest.onreadystatechange = ()=>{
if(xmlRequest.readystate === 4){
if(xmlRequest.state === 200){
xmlRequest.open('get', url)
console.log(xmlRequest.responseText)
// 2. 指定进入成功状态时的回调函数的逻辑
resolve(xmlRequest.responseText)
}else{
// 3. 指定进入失败状态时的回调函数的逻辑
reject('失败了')
}
}
}
})
// 返回promise以创建下一条链式调用
return promise
}
getNews(url)
.then((data)=>{
// fullfilled状态,步骤2中的回调函数
let {newUrl} = JSON.parse(data)
// 返回promise以继续创建下一条链式调用
return getNews(newUrl) // 重新创建了新的promise来重复执行函数getNews
}, (error)=>{
// rejected状态,步骤3中的回调函数
console.log(error)
})
.then((data)=>{
// fullfilled状态,步骤2中的回调函数
console.log('完成')
}, (error)=>{
// rejected状态,步骤3中的回调函数
console.log(error)
})
.catch(error=>{ //通常不会给then指定第二个错误回调,而是使用catch方法来捕获错误
console.log(error)
})
.finally(()=>{}) //在执行完then或者catch回调后就执行,本质两者回调中的逻辑交集,发布于ES8
用来封装异步操作并可以获取其成功或失败的结果:
1. Promise 构造函数: Promise (excutor) {};
2. Promise.prototype.then 方法(定义在原型对象Promise.prototype上,为Promise实例添加状态改变时的回调函数。);
3. Promise.prototype.catch 方法(定义在原型对象Promise.prototype上,是用于指定发生错误时的回调函数。);
构造函数基本语法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise</title>
</head>
<body>
<script>
// 实例化 Promise 对象
// Promise 对象三种状态:初始化、成功、失败
const p = new Promise(function(resolve,reject){
setTimeout(function(){
// 成功
// let data = "数据";
// 调用resolve,这个Promise 对象的状态就会变成成功
// resolve(data);
// 失败
let err = "失败了!";
reject(err);
},1000);
});
</script>
</body>
</html>
封装读取文件:
// 1、引入 fs 模块
const fs = require("fs");
// 2、调用方法,读取文件
// fs.readFile("resources/text.txt",(err,data)=>{
// // 如果失败则抛出错误
// if(err) throw err;
// // 如果没有出错,则输出内容
// console.log(data.toString());
// });
// 3、使用Promise封装
const p = new Promise(function(resolve,data){
fs.readFile("resources/text.txt",(err,data)=>{
// 判断如果失败
if(err) reject(err);
// 如果成功
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log(reason); // 读取失败
})
封装Ajax请求:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise封装Ajax请求</title>
</head>
<body>
<script>
// 请求地址:https://api.apiopen.top/getJoke
const p = new Promise(function(resolve,reason){
// 原生请求
// 1、创建对象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
// 3、发送
xhr.send();
// 4、绑定事件,处理响应结果
xhr.onreadystatechange = function(){
// 判断状态
if(xhr.readyState == 4){
// 判断响应状态码 200-299
if(xhr.status>=200 && xhr.status<=299){
// 成功
resolve(xhr.response);
}else{
// 失败
reason(xhr.status);
}
}
}
});
//指定回调
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log(reason); // 读取失败
})
</script>
</body>
</html>
Promise.prototype.then代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise.prototype.then</title>
</head>
<body>
<script>
// 创建 Promise 对象
const p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve("用户数据");
},1000);
});
// 调用then方法,then方法的返回结果是promise对象,
// 对象的状态有回调函数的结果决定;
const result = p.then(value => {
console.log(value);
// 1、如果回调函数中返回的结果是 非promise 类型的数据,
// 状态为成功,返回值为对象的成功值resolved
// [[PromiseStatus]]:"resolved"
// [[PromiseValue]]:123
// return 123;
// 2、如果...是promise类型的数据
// 此Promise对象的状态决定上面Promise对象p的状态
// return new Promise((resolve,reject)=>{
// // resolve("ok"); // resolved
// reject("ok"); // rejected
// });
// 3、抛出错误
// throw new Error("失败啦!");
// 状态:rejected
// value:失败啦!
},reason => {
console.error(reason);
})
// 链式调用
// then里面两个函数参数,可以只写一个
p.then(value=>{},reason=>{}).then(value=>{},reason=>{});
console.log(result);
</script>
</body>
</html>
Promise.prototype.catch代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Promise对象catch方法</title>
</head>
<body>
<script>
// Promise对象catch方法
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
// 设置p对象的状态为失败,并设置失败的值
reject("失败啦~!");
},1000);
})
// p.then(value=>{
// console.log(value);
// },reason=>{
// console.warn(reason);
// });
p.catch(reason=>{
console.warn(reason);
});
</script>
</body>
</html>