Promise 的基本概念Promise 是一个构造函数
-
-
我们可以创建 Promise 的实例 const p = new Promise()
-
new 出来的 Promise 实例对象,代表一个异步操作
-
-
Promise.prototype 上包含一个 .then() 方法
-
每一次 new Promise() 构造函数得到的实例对象
-
都可以通过原型链的方式访问到 .then()方法,例如 p,then()
-
-
.then() 方法用来预先指定成功和失败的回调函数
-
p.then(成功的回调函数,失败的回调函数)
-
p.then(result => { } , error => { })
-
调用 .then()方法时,成功的回调函数是必选的、失败的回调函数是可选的
-
Promise 回调地狱
const fs = require('fs')
const path = require('path')
let p1 = new Promise((resolve,reject)=>{
fa.readFile(path.join(__dirname,'读的文件路径'),'utf-8',(err,data)=>{
if(err) return reject(err)
resolve(data)
})
})
p1.then(
//成功
(res) =>{console.log(res)}
//失败
(err) =>{console.log(err)},
)
.then()方法的特性 解决回调地狱
如果上一个 .then() 方法中返回了一个新的Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通过 .then() 方法的链式调用,就解决了回调地狱的问题
const fs = require('fs')
const path = require('path')
function fn(fpath) {
return new Promise((resolve, reject) => {
fs.readFile(fpath, 'utf8', (err, data) => {
if (err) return reject(err)
resolve(data)
})
})
}
fn(path.join(__dirname, './1.txt')).then(
//成功
(res) => {
console.log(res) //111
// 返回一个promise
return fn(path.join(__dirname, './2.txt'))
}
)
.then(
(res) => {
//成功
console.log(res) //222
// 返回一个promise
return fn(path.join(__dirname, './3.txt'))
}
)
.then(
//成功
(res) => console.log(res), //333
)
.catch() 方法捕获错误
const fs = require('fs')
const path = require('path')
function fn(fpath) {
return new Promise((resolve, reject) => {
fs.readFile(fpath, 'utf8', (err, data) => {
if (err) return reject(err)
resolve(data)
})
})
}
fn(path.join(__dirname, './11.txt')).catch(err => {
// 最后捕获的错误
// ENOENT: no such file or directory
// 提前捕获的错误
// undefined
//222
//333
console.log(err.message);
}).then(
(res) => {
console.log(res) //111
// 返回一个promise
return fn(path.join(__dirname, './2.txt'))
}
).then(
(res) => {
console.log(res) //222
// 返回一个promise
return fn(path.join(__dirname, './3.txt'))
}
).then(
(res) => console.log(res), //333
)
Promise.all() 方法
Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then 操作(等待机制)。
const promiseArr = [
fn(path.join(__dirname, './1.txt')),
fn(path.join(__dirname, './2.txt')),
fn(path.join(__dirname, './3.txt')),
]
Promise.all(promiseArr).then(([r1, r2, r3]) => {
// 按顺序执行
console.log(r1, r2, r3);
//111 222 333
}).catch((err) => {
console.log(err.message);
})
Promise.race() 方法
Promise.race() 方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即执行下一步的 .then 操作(赛跑机制)。
const promiseArr = [
fn(path.join(__dirname, './1.txt')),
fn(path.join(__dirname, './2.txt')),
fn(path.join(__dirname, './3.txt')),
]
//打印执行最快的
Promise.race(promiseArr).then((result) => {
// 111是执行最快的
console.log(result);
}).catch((err) => {
console.log(err.message);
})
async/await(重点 项目必用)
async/await 是 ES8 引入的新语法,用来简化 Promise 异步操作。在async/await 出现之前,爱看i发者只能通过链式 .then() 的方法来处理 Promise 异步操作
async/await 简化 promise的异步操作
const thenFs = require('then-fs')
async function getAllFile(){
const r1 = await thenFs.readFile('读的文件','utf8')
console.log(111)
const r2 = awiat thenFs.readFile('读的文件','utf8')
console.log(222)
const r3 = awit thenFs.readFile('读的文件','utf8')
console.log(333)
}
getAllFile()
async/await 的使用注意事项
① 如果在 function 中使用了 await,则 function 必须被 async 修饰
② 在 async 方法中,第一个 await 之前的代码会同步执行,await 之后的代码会异步执行