异步操作是 JavaScript 编程的麻烦事,麻烦到一直有人提出各种各样的方案,试图解决这个问题。早期使用回调函数处理异步编码,但存在回调地狱的问题。ES6中,新增了Promise 对象,从此异步编程摆脱了回调函数的束缚。
使用语法
let p = new Promise((resolve, reject) => {
// ... some code
if (/* 异步操作成功 */) {
resolve(value);
} else {
reject(error);
}
})
注意点:
- new Promise()
- 必须传入一个函数作为Promise的参数,这个函数在 new Promise的时候就会执行
- 函数有 resolve 和 reject 两个形参
- 函数就相当于一个容器,可以将异步任务放到这里
- 将异步任务成功的结果传给 resolve 函数;将失败的信息传给 reject 函数
p.then(
result => { /* 获取成功的结果 */ }
);
// 或者
p.then(
result => { /* 获取成功的结果 */ },
err => { /* 获取失败的结果 */ }
)
// 或者
// 一般使用
p.then(
result => { /* 获取成功的结果 */ }
).catch(
err => { /* 获取失败的结果 */ }
)
注意点:
- then方法接收以个函数类型的参数,只处理成功
- then方法接收两个函数类型的参数,分别用于接收 resolve 的值 和 reject 的值
- then方法也可以只接收一个参数,表示只接收 resolve 的值,失败的结果可以通过链式调用catch方法捕获
2.1 Promise中的同步异步
new Promise 和 new 其他对象一样,是同步任务。 获取结果时(调用 resolve 触发 then方法时)是异步的。
2.2 使用Promise解决回调地狱
// 导入es6模块
import { readFile } from 'fs'
// 封装一个方法,可以获取 Promise对象 - axios.js未来第三方模块,几乎全部支持 Promise对象开发
function fn (url){
return new Promise ((resolve,rejects)=>{
readFile(url,"utf8",(err,data)=>{
resolve(data)
})
})
}
//调用
fn(./txt/a.txt).then(res=>{
console.log(res)
resturn fn(./txt/b.txt)
})
fn(./txt/b.txt).then(res=>{
console.log(res)
resturn fn(./txt/c.txt)
})
fn(./txt/c.txt).then(res=>{
console.log(res)
})
2.3 第三方then-fs解决回调地狱
// 下载 npm i then-fs
import thenFs from 'then-fs'
// 利用 then-Fs 模块解决回调地狱
thenFS.readFile ('./txt/a.txt',"utf8").then(res={
console.log(res)
return thenFs.readFile('./txt/b.txt',"utf8")
})then(res=>{
console.log(res)
return thenFs.readFile('./txt/c.txt')
})then(res=>{
console.log(res)
})
注意: 未来很多模块支持Promise对象开发,就是返回的是一个Promise对象; 如 axios