为了解决回调地狱的问题,ES6(ECMAScript 2015)中新增了 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() 方法时,成功的回调函数是必选的、失败的回调函数是可选的
'总结:1.可以通过new构造函数创建一个Promise对象;2.p原型链上有then方法,预先指定成功和失败的回调函数,失败可省略
2.像之前axios指向的就是一个Promise实例对象,为了简化通过async,await来取代then
'
实际开发中:
1、then()方法是异步执行。
意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。通常用在ajax请求后面
2、catch()方法防止因为错误而造成系统崩溃
在程序逻辑中, 需要在易出现问题的逻辑代码片段上, 加持catch方法, 这样做可以捕获错误, 但是不会影响整个程序运转;
npm install then-fs //node.js 官方提供的 fs 模块仅支持以回调函数的方式读取文件,不支持 Promise 的调用方式
import thenFs from 'then-fs'
thenFs.readFile('./1.txt', 'utf8').then(
(r1) => {
console.log(r1)
},
(err1) => {
console.log(err1.messgae)
}
)
thenFs.readFile('./2.txt', 'utf8').then(
(r2) => {
console.log(r2)
},
(err2) => {
console.log(err2.messgae)
}
)
thenFs.readFile('./3.txt', 'utf8').then(
(r3) => {
console.log(r3)
},
(err3) => {
console.log(err3.messgae)
}
)
import thenFs from 'then-fs'
// 通过return返回一个新的Promise实例对象,因为Promise中有.then就会执行下句代码
// .then() 方法的链式调用
thenFs
.readFile('./1.txt', 'utf8')
.then((r1) => {
console.log(r1)
return thenFs.readFile('./2.txt', 'utf8')
})
.then((r2) => {
console.log(r2)
return thenFs.readFile('./3.txt', 'utf8')
})
.then((r3) => {
console.log(r3)
})
捕获在链式操作中逻辑代码上的问题,防止因为错误造成系统崩溃
一旦发现代码或者系统有错误,就会直接报出错误的原因
import thenFs from 'then-fs'
// 通过return返回一个新的Promise实例对象,因为Promise中有.then就会执行下句代码
// .then() 方法的链式调用
thenFs
.readFile('./1.txt', 'utf8')
.then((r1) => {
console.log(r1)
return thenFs.readFile('./2.txt', 'utf8')
})
.then((r2) => {
console.log(r2)
return thenFs.readFile('./3.txt', 'utf8')
})
.then((r3) => {
console.log(r3)
})
.catch((err) => {
console.log(err.message)
})
在.then链式调用中,放在最后就会出现一旦第一个报错就会终止程序,不能输出后面的结果
因此为了解决,放前,由于错误被及时处理,就不会影响后续.then的正常执行
import thenFs from 'then-fs'
// 通过return返回一个新的Promise实例对象,因为Promise中有.then就会执行下句代码
// .then() 方法的链式调用
thenFs.readFile('./1.txt', 'utf8')
.catch((err) => {
console.log(err.message)
})
.then((r1) => {
console.log(r1)
return thenFs.readFile('./2.txt', 'utf8')
})
.then((r2) => {
console.log(r2)
return thenFs.readFile('./3.txt', 'utf8')
})
.then((r3) => {
console.log(r3)
})
这个方法是等所有异步操作执行完之后才执行.then操作
import thenFs from 'then-fs'
const promiseArr = [
thenFs.readFile('./1.txt', 'utf8'),
thenFs.readFile('./2.txt', 'utf8'),
thenFs.readFile('./3.txt', 'utf8')
]
Promise.all(promiseArr)
.then((result) => {
console.log(result) // 所有结果
})
.catch((err) => {
console.log(err.message)
})
只要有一个异步操作完成,就进入.then异步操作 // 本文中 thenFs 是一个读取文件插件,返回的是一个 Promise 实例
import thenFs from 'then-fs'
const promiseArr = [
thenFs.readFile('./1.txt', 'utf8'),
thenFs.readFile('./2.txt', 'utf8'),
thenFs.readFile('./3.txt', 'utf8')
]
Promise.race(promiseArr)
.then((result) => {
console.log(result) // 结果
})
.catch((err) => {
console.log(err.message)
})
1.声明一个加载成功的函数
2.声明一个加载超时的函数
3.利用promise在race方法完成异步加载
//需求:把成功和失败的放在race方法中,哪个先执行完,就先进入.then输出结果.成功函数没有加载完成,5s后就会触发超时函数
// 1.声明加载完成的函数
function requestImg(){
//实例化promise resolve捕获成功信息 reject捕获失败信息
var p =new Promise((resolve,reject)=>{
//创建图片
var img = new Image();
//页面加载完成之后执行
img.onload=()=>{
resolve(img);
}
img.src="路径";
})
//返回promise实例
return p;
}
//2.声明加载超时的函数
function timeOut(){
var p= new Promise((resolve,reject)=>{
//一次性定时器
setTimeout(()=>{
//返回图片加载超时提示
reject("图片加载超时")
},5000)
})
//返回promise实例
return p;
}
//3.调用promise的race方法进行两个函数的加载
Promise.race([requestImg(),timeOut()]).then((res)=>{
//打印成功
console.log(res)
}).catch((err)=>{
//打印失败
console.log(err)
})
promise就是处理异步的;
promise.all就是等所有异步执行完再返回结果(按顺序执行所有、按顺序返回所有)
promise.race就是哪个异步先执行完就返回哪个结果(只返回最快执行完的那个)
promise本身是同步的,但是他的.then和.catch是异步
promise作用:解决代码中回调函数嵌套使用的臃肿问题,它有.then和.catch两个异步方法,
import fs from 'fs'
function getFile(fpath){
//返回一个promise对象 resolve捕获成功信息,reject捕获失败信息
return new Promise(function(resolve,reject){
//err是错误,成功拿到dataStr
fs.readFile(fpath,'utf8',(err,dataStr)=>{
if(err) return reject(err)
resolve(dataSStr)
})
})
}
const promiseArr=[
getFile('./1.txt')
getFile('./2.txt')
getFile('./3.txt')
]
Promise.all(promiseArr)
.then((result) => {
console.log(result) // 所有结果
})
.catch((err) => {
console.log(err.message)
})
Promise.race(promiseArr)
.then((result) => {
console.log(result) // 结果
})
.catch((err) => {
console.log(err.message)
})
1.async/await 是 ES8(ECMAScript 2017)引入的新语法,用来简化 Promise 异步操作。在 async/await 出
现之前,开发者只能通过链式 .then() 的方式处理 Promise 异步操作
2.await修饰Promise实例对象====>>>>>值,async修饰调用方法
import thenFs from 'then-fs'
async getfile(){
const r1 = await thenFs.readFile('./1.txt', 'utf8') //thenFs这个是一个实例对象,用await修饰
console.log(r1) //111
const r2 = await thenFs.readFile('./2.txt', 'utf8')
console.log(r2) ///222
}
getfile()
① 如果在 function 中使用了 await,则 function 必须被 async 修饰
② 在 async 方法中,第一个 await 之前的代码会同步执行,await 之后的代码会异步执行
// A B C 111 222 333 D
现在就还差一点需要说明,那就是怎么处理异常,如果请求发生异常,怎么处理? 它用的是try/catch 来捕获异常,把await 放到 try 中进行执行,如有异常,就使用catch 进行处理。
import thenFs from 'then-fs'
async getfile(){
try{
const r1 = await thenFs.readFile('./1.txt', 'utf8') //thenFs这个是一个实例对象,用await修饰
console.log(r1) //111
} catch(err){
console.log(err)
}
getfile()