Promise 基本使用
Promise
是 ES6 引入的解决异步编程的新解决方案。语法上 Promise
是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数:
Promise(excutor){}
Promise.prototype.then
方法Promise.prototype.catch
方法
// 实例化 Promise 对象
const p = new Promise(function(resolve,reject){
setTimeout(function(){
// 成功
let data = '数据库中的用户数据'
resolve(data)
// 失败
let err = '数据读取失败'
reject(err)
},1000)
})
// 调用 promise 对象的 then 方法
// 两个函数, 成功的形参叫value,失败的形参叫reason
p.then(function(value){ //成功
console.log(value);
},function(reason){ //失败
console.log(reason);
})
Promise 读取文件
读取方法一:调用方法读取文件
- 创建
为学.md
文件
为之,则难者易易也
不为,则易者亦难矣
- 创建
Promise读取文件.js
文件
// 1.引入 fs 模块
const fs = require('fs')
// 2.调用方法读取文件
fs.readFile('为学.md',(err, data)=>{
// 如果失败,则抛出错误
if(err) throw err
// 如果没有,则输出内容
console.log(data.toString());
})
- 终端输入命令
node Promise读取文件.js
回车。
读取方法二:使用 Promise 封装
- 创建
为学.md
文件
为之,则难者易易也
不为,则易者亦难矣
- 创建
Promise读取文件.js
文件
const p = new Promise(function(resolve,reject){
fs.readFile('为学.md',(err, data)=>{
// 判断如果失败
if(err) reject(err)
// 如果成功
resolve(data)
})
})
p.then(function(value){
console.log(value.toString())
},function(reason){
console.log("读取失败!!");
})
- 终端输入命令
node Promise读取文件.js
回车。
读取成功
读取失败(如 '为学.md' 的路径错误)
Promise 封装 AJAX
接口地址:https://api.apiopen.top/getJoke
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.log(reason);
})
成功输出
输出失败:404
Promise.prototype.then 方法
调用 then 方法
,then 方法
的返回结果是 Promise 对象
,对象的状态由回调函数的结果决定。
如果回调函数中返回的结果是 非 Promise 类型
的属性,状态为成功 返回值为对象的成功值
- 非 promise 类型的属性
// 创建 promise 对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据')
// reject('出错啦')
},1000)
})
const result = p.then(value => {
console.log(value)
// 1.非 promise 类型的属性
return 123
}, reason => {
console.warn(reason) //console.warn() 在控制台上输出警告信息
})
console.log(result);
- 是 promise 对象
// 创建 promise 对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据')
// reject('出错啦')
},1000)
})
const result = p.then(value => {
console.log(value)
// 2.是 promise 对象
return new Promise((resolve, reject)=>{
// resolve('ok')
reject('error')
})
}, reason => {
console.warn(reason) //console.warn() 在控制台上输出警告信息
})
console.log(result);
resolve('ok')的情况下:
reject('error')的情况下:
- 抛出错误
// 创建 promise 对象
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据')
// reject('出错啦')
},1000)
})
const result = p.then(value => {
console.log(value)
// 3.抛出错误
throw '出错啦'
}, reason => {
console.warn(reason) //console.warn() 在控制台上输出警告信息
})
console.log(result);
Promise 实践
读取三个 .md 文件,三个文件合在一起输出
- 回调的方式 (回调地狱)
// 引入 fs 模块
const fs = require("fs")
const { resolve } = require("path/posix")
//1.回调的方式
fs.readFile('为学.md',(err, data1)=>{
fs.readFile('插秧诗.md',(err,data2)=>{
fs.readFile('观书有感.md',(err,data3)=>{
let result = data1 + '\r\n' + data2 + '\r\n' + data3
console.log(result);
})
})
})
2. 通过 promise 实现
const fs = require("fs")
const { resolve } = require("path/posix")
// 2.使用 promise 实现
const p = new Promise((resolve, reject)=>{
fs.readFile('为学.md',(err,data)=>{
resolve(data)
})
})
p.then(value=>{
return new Promise((resolve, reject)=>{
fs.readFile('插秧诗.md',(err,data)=>{
resolve([value, data])
})
})
}).then(value => {
return new Promise((resolve, reject)=>{
fs.readFile('观书有感.md',(err,data)=>{
//压入
value.push(data)
resolve(value)
})
})
}).then(value=>{
console.log(value.join('\r\n')); // \r\n 表示换行
})
Promise-catch 方法
用来指定 promise 对象失败的回调。
- 使用
then 方法
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
// 设置 p 对象的状态为失败, 并设置失败的值
reject("出错啦")
},1000)
})
p.then(function(value){},function(reason){
console.error(reason);
})
2. 使用 catch
const p = new Promise((resolve, reject)=>{
setTimeout(()=>{
// 设置 p 对象的状态为失败, 并设置失败的值
reject("出错啦")
},1000)
})
p.catch(function(reason){
console.warn(reason);
})
不积跬步无以至千里 不积小流无以成江海