Promise 基本使用
Promise 是 ES6 引入的解决异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
- 1.Promise 构造函数:Promise(excutor){}
- 2.Promise.prototype.then 方法
- 3.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 读取文件
读取方法一:调用方法读取文件
- 1.创建 为学.md 文件
为之,则难者易易也 不为,则易者亦难矣
- 2.创建 Promise读取文件.js 文件
// 1.引入 fs 模块 const fs = require('fs') // 2.调用方法读取文件 fs.readFile('为学.md',(err, data)=>{ // 如果失败,则抛出错误 if(err) throw err // 如果没有,则输出内容 console.log(data.toString()); })
- 3.终端输入命令 node Promise读取文件.js 回车。
- 读取方法二:使用 Promise 封装
- 1.创建
为学.md
文件
为之,则难者易易也 不为,则易者亦难矣
- 2.创建 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("读取失败!!"); })
3.终端输入命令 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 类型 的属性,状态为成功 返回值为对象的成功值
1.非 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);
- 2.是 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')的情况下:
- 3.抛出错误
// 创建 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 文件,三个文件合在一起输出
- 1.回调的方式 (回调地狱)
// 引入 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 对象失败的回调。
- 1.使用 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); })
阮一峰 ES6-Promise:https://es6.ruanyifeng.com/#docs/promise
不积跬步无以至千里 不积小流无以成江海