一、什么是Promise
1、Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
二、Promise基本语法
1、Promise接收一个函数类型的参数。这个函数有两个入参。入参名字可以叫resolve和reject。
2、把异步函数封装在Promise对象中,成功调用resolve(),失败调用reject()。
- //实例化 Promise 对象
- const p = new Promise(function(resolve, reject){
- setTimeout(function(){
- //模拟获取数据
- let data = '数据库中的用户数据';
- //调用resolve
- resolve(data);
- //调用后p的状态会变成成功
- }, 1000);
- });
-
- //调用 Promise 对象的 then 方法
- p.then(function(value){ //它有两个形参,成功的形参叫value
- //当你调用resolve(),Promise对象状态为成功时,调用第一个函数
- console.log(value);
- }, function(reason){ //失败的形参叫reason
- //如果调用reject(),Promise对象状态为失败,调用第二个函数
- console.error(reason);
- });
一秒钟后,控制台打印:数据库中的用户数据
3、Promise构造函数:Promise(excutor){}
4、Promise.prototype.then方法
5、Promise.prototype.catch方法
三、Promise读取文件
1、例子使用了nodejs的fs库
Promise读取文件.js
- //1. 引入 fs 模块
- const fs = require('fs');
-
- //2. 调用方法读取文件
- // fs.readFile('./let关键字.html', (err, data) => {
- // //如果失败,则抛出错误
- // if(err) throw err;
- // //如果没有出错,则输出内容
- // console.log(data.toString());
-
- // });
-
- //3. 使用Promise封装
- const p = new Promise(function(resolve, reject){
- fs.readFile('./let关键字.html', (err, data) => {
- //判断如果失败
- if (err) reject(err);
- //如果成功
- resolve(data);
-
- });
- })
-
- p.then(function(value){
- console.log(value.toString());
- }, function(reason){
- console.log("读取失败!");
- });
执行:
D:\workspace-vscode\ECMAScript6> node .\Promise读取文件.js
2、要是有多个异步任务,代码要不断的往里面缩进,但是使用Promise就不会。
四、Promise封装ajax请求
1、接口地址:https://api.apiopen.top/api/sentences
- const p = new Promise((resolve, reject)=>{
- //1. 创建对象
- const xhr = new XMLHttpRequest();
-
- //2. 初始化
- xhr.open("GET", "https://api.apiopen.top/api/sentences");
-
- //3. 发送
- xhr.send();
-
- //4. 绑定事件,处理响应结果
- xhr.onreadystatechange = function(){
- //判断
- if(xhr.readyState === 4){
- //判断响应状态码
- if(xhr.status >= 200 && xhr.status <300){
- //表示成功
- //console.log(xhr.response);
- resolve(xhr.response);
- }else{
- //如果失败
- //console.error(xhr.status);
- reject(xhr.status);
- }
- }
- }
- });
-
- //指定回调
- p.then(function(value){
- console.log(value);
- }, function(reason){
- console.error(reason);
- });
Promise把调用和数据处理分开来了,代码更简洁。
五、Promise.prototype.then方法
1、如果回调函数中返回的结果是非 Promise 类型的属性,则返回对象状态为成功,对象的值为返回值。
- //创建 Promise 对象
- const p = new Promise((resolve, reject)=>{
- setTimeout(()=>{
- resolve('用户数据');
- }, 1000);
- });
-
- //调用 then 方法,两个回调函数
- const result = p.then(value=>{
- console.log(value);
- return 123;
- }, reason=>{
- console.warn(reason);
- });
-
- //then 方法的返回结果是 Promise 对象,对象状态是由回调函数的执行结果决定的
- console.log(result);

2、状态
pending:初始状态,不是成功或失败状态。
fulfilled:意味着操作成功完成。
rejected:意味着操作失败。
3、如果回调函数返回的是 Promise 对象,则 then 方法返回的就是这个对象。
4、then链式调用
p.then(value=>{}, reason=>{}).then(value=>{}, reason=>{});
链式调用,可以避免回调地狱的现象。
六、Promise读取多个文件,解决回调地狱现象
1、挨个读取三个文件内容,将读的内容合在一起输出
- //1. 引入 fs 模块
- const fs = require("fs");
-
- //回调地狱方式实现
- // fs.readFile('./let关键字.html', (err1, data1)=>{
- // fs.readFile('./const关键字.html', (err2, data2)=>{
- // fs.readFile('./let关键字实例.html', (err3, data3)=>{
- // let result = data1 + + '\r\n' + data2 + '\r\n' + data3;
- // console.log(result);
- // });
- // });
- // });
-
- //使用 Promise 实现
- //读取第一个文件
- const p = new Promise((resolve, reason)=>{
- fs.readFile('./let关键字.html', (err1, data1)=>{
- //成功
- resolve(data1);
- });
- });
-
- //第一个Promise的回调
- p.then(value=>{
- //返回一个新的Promise读取第二个文件
- return new Promise((resolve, reject)=>{
- fs.readFile("./const关键字.html", (err, data2)=>{
- //成功
- resolve([value, data2]); //value是读第一个文件的返回,data2是读第二个文件的返回
- });
- });
- }).then(value=>{
- return new Promise((resolve, reject)=>{
- fs.readFile("./let关键字实例.html", (err, data3)=>{
- //成功
- value.push(data3); //压入
- resolve(value); //value是三个文件的返回结果的数组
- });
- });
- }).then(value=>{
- console.log(value.join('\r\n'));
- });
七、Promise的catch方法
1、catch方法
用来指定Promise对象失败的一个回调。
- DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <title>Promise的catch方法title>
- <style>
-
- style>
- head>
-
- <body>
- <h1 id="hid" class="hcls"><span>testspan>h1>
- body>
-
- <script>
- const p = new Promise((resolve, reject)=>{
- //模拟操作
- setTimeout(()=>{
- //设置p对象的状态为失败,并设置失败的值
- reject("出错啦!");
- }, 1000);
- });
-
- // p.then(value=>{}, reason=>{
- // console.error(reason);
- // });
-
- //catch只回调状态失败时的回调方法
- p.catch(reason=>{
- console.warn(reason);
- });
-
- script>
-
- html>