十三、Promise
大约 4 分钟约 1130 字
(一)基本语法
Promise
是ES6
引入的异步编程的新解决方案- 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
- Promise 构造函数:
Promise (excutor) {}
Promise.prototype.then
方法Promise.prototype.catch
方法
// 实例化Promise对象
const p = new Promise(function (resolve, reject) {
setTimeout(function () {
// 获得一个数据
let data = "数据库中的用户数据";
// // 调用resolve后p对象状态变为“成功”
// resolve(data);
// 调用reject后p对象状态变为“失败”
reject(data);
}, 1000);
});
// 调用Promise对象的then方法
p.then(
function (value) {
// p为成功时执行
console.log(value);
},
function (reason) {
// p为失败时指向
console.error(reason);
},
);
(二)读取文件
为学
天下事有难易乎?
为止,则难者亦易矣;
不为,则易者亦难矣。
// 1.引入nodejs中的fs模块
const fs = require("fs");
// 2.调用方法读取文件
// fs.readFile("./resources/为学.md", (err, data) => {
// // 如果失败则抛出错误
// if (err) throw err;
// // 如果成功则输出内容
// console.log(data.toString());
// /**
// * cd '.\ECMAScript6-11\'
// * node .\21.Promise读取文件.js
// */
// });
// 3.使用Promise封装
const p = new Promise(function (resolve, reject) {
fs.readFile("./resources/为学.md", (err, data) => {
// 如果失败
if (err) reject(err);
// 如果成功
resolve(data);
});
});
p.then(
function (value) {
console.log(value.toString());
},
function (reason) {
console.log("读取失败!");
},
);
(三)发送 Ajax 请求
1.传统 xhr
// 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 < 300) {
// 表示成功
console.log(xhr.response);
} else {
// 如果失败
console.error(xhr.status);
}
}
};
2.使用 Promise 封装
const p = new Promise((resolve, reject) => {
// 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 < 300) {
// 表示成功
resolve(xhr.response);
} else {
// 如果失败
reject(xhr.status);
}
}
};
});
// 指定回调
p.then(
function (value) {
console.log(value);
},
function (reason) {
console.error(reason);
},
);
(四)Promise.prototype.then
1.调用 then 方法
// 创建Promise对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("用户数据");
// reject('出错啦');
}, 1000);
});
p.then(
(value) => {
console.log(value);
},
(reason) => {
console.warn(reason);
},
);
2.then 方法返回的结果
then
方法的返回结果是Promise
对象- 对象状态由回调函数的执行结果来决定
- 回调函数中返回的结果是 非 Promise 类型 的数据 =>
resolve
(状态成功,返回值为对象的成功的值)
const result = p.then(
(value) => {
console.log(value);
// 0.没有返回值
// [[PromiseState]]: "fulfilled"
// [[PromiseResult]]: undefined
// 1.非Promise类型
// return 123;
// // [[PromiseState]]: "fulfilled"
// // [[PromiseResult]]: 123
// 2.是Promise对象
// return new Promise((resolve, reject) => {
// // Promise内部任务多数是异步的,但是也可以是同步任务
// // resolve('ok');
// // // [[PromiseState]]: "fulfilled"
// // // [[PromiseResult]]: "ok"
// reject("error");
// // [[PromiseState]]: "rejected"
// // [[PromiseResult]]: "error"
// });
// 3.抛出错误
throw new Error("出错啦!");
// [[PromiseState]]: "rejected"
// [[PromiseResult]]: Error: 出错啦!
},
(reason) => {
console.warn(reason);
},
);
console.log(result);
3.then 方法可以链式调用
- 指定回调可以只指定一个成功或者一个失败
p.then((reason) => {
console.log(reason);
}).then((value) => {
console.log(value);
});
(五)读取多个文件
插秧诗
布袋和尚
手把青秧插满田,
低头便见水中天。
心地清净方为道,
退步原来是向前。
观书有感
作者:朱熹
半亩方塘一鉴开,
天光云影共徘徊。
问渠那得清如许?
为有源头活水来。
1.回调地狱读取文件
// 引入fs模块
const fs = require("fs");
// 回调地狱读取文件
fs.readFile("./resources/为学.md", (err1, data1) => {
fs.readFile("./resources/插秧诗.md", (err2, data2) => {
fs.readFile("./resources/观书有感.md", (err3, data3) => {
let result = `${data1}\r\n${data2}\r\n${data3};`;
console.log(result);
});
});
});
2.使用 Promise 实现
// 引入fs模块
const fs = require("fs");
const p = new Promise((resolve, reject) => {
fs.readFile("./resources/为学.md", (err, data) => {
resolve(data);
// data是buffer类型,使用toString转为可读字符串
});
});
p.then((value) => {
// console.log(value.toString());
return new Promise((resolve, reject) => {
fs.readFile("./resources/插秧诗.md", (err, data) => {
resolve([value, data]);
});
});
})
.then((value) => {
// console.log(value); // 为学+插秧诗
return new Promise((resolve, reject) => {
fs.readFile("./resources/观书有感.md", (err, data) => {
// 压入
value.push(data);
resolve(value);
});
});
})
.then((value) => {
console.log(value.join("\r\n"));
});
(六)Promise.prototype.catch
// 创建Promise对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// 设置p对象的状态为失败,并设置失败的值
reject("出错啦");
}, 1000);
});
p.then(
(value) => {},
(reason) => {
console.error(reason);
},
);
// 指定Promise失败的回调
p.catch((reason) => {
console.warn(reason);
});