异步操作
- 封装异步操作手动
let p = new Promise((resolve,reject)=>{
//异步操作
//成功调resolve()
//失败调reject()
})
//第一个callback就是resolve(),第二个是reject()
p.then(callback,callback)
- 封装异步操作
util.promisify()
nodejs
内置的模块util
,方法.promisify()
可以将一个需要封装的函数自动封装并返回一个promise
对象- 导入
- 使用
//导入util模块
const util = require('util')
const fs = require('fs')
//封装fs的readFile方法
let p = util.promisify(fs.readFile)
//此时的p就相当于fs.readFile函数,只不过他是一个promise函数
p('./test.text').then(
value => {
console.log(value.toString());
},
err => {
console.log(err.message);
}
)
util.promisify()参数为一个错误优先的回调函数,即(err,data)=>{}
promise的状态
-
pending
未决定的 -
resolved/fullfilled
成功 -
rejected
失败 -
只能由pending变为成功或者失败
-
一个对象只能改变一次状态一般成功的结果是
value
,失败的结果是reason
promise的值
PromiseResult
属性上存在成功或失败的结果
then
- 他的返回值也是一个
promise
对象 - 返回状态由执行回调的返回值决定
- 如果执行的是成功/失败回调❗没写错
不return
,返回成功状态promise
对象,值为undefined
抛出错误
,返回失败状态的promise
对象,值为抛出的错误return 非promise对象值
,返回成功状态promise
对象,值为return的非promise对象值return promise对象
,返回的promise
对象的状态和值与return
的promise
对象的状态和值保持一致
- 如果执行的是成功/失败回调❗没写错
- 当被
promise
对象调用时,如果是成功状态就调用then
的第一个回调并传成功的值
不管执行哪个回调都是这4点
cath
- 只能执行失败的回调
Promise.resolve(option)
- 是构造函数
Promise
的方法。不是实例的方法 - 如果
option
是非promise
对象,则resolve
返回成功状态的promise
对象,且值为option
- 如果
option
是promise
对象,则resolve返回状态和值与option
的状态和值一致
Promise.reject(option)
- 是构造函数
Promise
的方法。不是实例的方法 - 只能返回失败状态的
promise
对象,而返回的promise
对象的值为option
Promise.all([p1,p2,p3])
- 是构造函数
Promise
的方法。不是实例的方法 - 参数中所有的
promise
对象的状态成功才会返回成功状态的promise
对象,且值为所有成功的promise
对象的值所组成的数组 - 参数中如果有失败状态的
promise
对象,那就会返回失败状态的promise对象,且值为第一个失败状态的promise
对象的值
let p1 = Promise.resolve('p1')
let p2 = Promise.resolve('p2')
let p3 = Promise.reject('p3')
let p4 = Promise.reject('p4')
console.log(Promise.all([p1, p2, p3, p4]));
/*
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: "p3"
*/
let p1 = Promise.resolve('p1')
let p2 = Promise.resolve('p2')
console.log(Promise.all([p1, p2]));
/*
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "resolved"
[[PromiseResult]]: "Array[p1,p2]"
*/
Promise.race([p1,p2,p3])
- 是构造函数
Promise
的方法。不是实例的方法 - 传入的
promise
对象谁先改变状态,那返回的promise
对象的状态和值与器保持一致
问题
-
改变
promise
状态.resolve()
.reject()
throw
抛出错误
-
只要
promise
状态改变,为他所定义多有回调都会执行(就是多个then
都会执行) -
异常穿透
- 链式调用
then
只需要最后调一个catch
错误回调即可,他会在出现失败状态promise
对象后调用
- 链式调用
-
中断链式调用
- 返回一个
pending
状态的promise
对象new Promise(()=>{})
- 返回一个
重写Promise构造函数
- 第一种
//把他们包在一个定时器里主要是为了让实例和Promise的方法都是异步的,当然也可以给他的方法里面的细节去加定时器(推荐),还有其他方法百度或者源码
setTimeout(() => {
//声明
function Promise (executor) {
//保存this
let _this = this
//声明状态和值
this.promiseState = 'pending'
this.promiseResult = null
//声明存储异步then的回调的数组
this.callback = []
//改变状态为成功的函数
function resolve (data) {
//判断状态是否已经更改,防止改第二次
if (_this.promiseState !== 'pending') return
//设置状态和值
_this.promiseState = 'fulfilled'
_this.promiseResult = data
//执行then失败的回调(异步)
_this.callback.forEach(item => {
item.onResolved(data)
})
}
//改变状态为失败的函数
function reject (data) {
//判断状态是否已经更改,防止改第二次
if (_this.promiseState !== 'pending') return
//设置状态和值
_this.promiseState = 'rejected'
_this.promiseResult = data
//执行then失败的回调(异步)
_this.callback.forEach(item => {
item.onRejected(data)
})
}
//抛出异常处理
try {
//同步调用执行器函数
executor(resolve, reject)
} catch (data) {
reject(data)
}
}
//添加then
Promise.prototype.then = function (onResolved, onRejected) {
let _this = this
//判断传递的参数是不是函数,若不是,给默认函数
if (typeof onResolved !== 'function') {
onResolved = value => value
}
if (typeof onRejected !== 'function') {
onRejected = reason => { throw reason }
}
//返回一个Promise对象
return new Promise((resolve, reject) => {
//封装重复代码
function callback (type) {
try {
//判断回调返回类型
let result = type(_this.promiseResult)
if (result instanceof Promise) {
result.then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
//判断状态,决定执行成功或失败回调
if (_this.promiseState === 'fulfilled') {
callback(onResolved)
}
if (_this.promiseState === 'rejected') {
callback(onRejected)
}
//如果是异步,那就要把then的回调保存起来,等状态改变时再调用对应回调
if (_this.promiseState === 'pending') {
_this.callback.push({
onResolved: () => {
callback(onResolved)
},
onRejected: () => {
callback(onRejected)
}
})
}
})
}
//添加catch
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
//添加resolve方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
value => {
resolve(value)
},
reason => {
reject(reason)
})
} else {
resolve(value)
}
})
}
//添加reject方法
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加all方法
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
promises.forEach((item, index) => {
item.then(
value => {
count++,
arr[index] = value
if (index === promises.length - 1) {
resolve(arr)
}
},
reason => {
reject(reason)
}
)
});
})
}
//添加race方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach(item => {
item.then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
});
})
}
})
- 第二种类封装
setTimeout(()=>{
class Promise {
constructor(executor) {
//保存this
let _this = this
//声明状态和值
this.promiseState = 'pending'
this.promiseResult = null
//声明存储异步then的回调的数组
this.callback = []
//改变状态为成功的函数
function resolve (data) {
//判断状态是否已经更改,防止改第二次
if (_this.promiseState !== 'pending') return
//设置状态和值
_this.promiseState = 'fulfilled'
_this.promiseResult = data
//执行then失败的回调(异步)
_this.callback.forEach(item => {
item.onResolved(data)
})
}
//改变状态为失败的函数
function reject (data) {
//判断状态是否已经更改,防止改第二次
if (_this.promiseState !== 'pending') return
//设置状态和值
_this.promiseState = 'rejected'
_this.promiseResult = data
//执行then失败的回调(异步)
_this.callback.forEach(item => {
item.onRejected(data)
})
}
//抛出异常处理
try {
//同步调用执行器函数
executor(resolve, reject)
} catch (data) {
reject(data)
}
}
//添加then
then (onResolved, onRejected) {
let _this = this
//判断传递的参数是不是函数,若不是,给默认函数
if (typeof onResolved !== 'function') {
onResolved = value => value
}
if (typeof onRejected !== 'function') {
onRejected = reason => { throw reason }
}
//返回一个Promise对象
return new Promise((resolve, reject) => {
//封装重复代码
function callback (type) {
try {
//判断回调返回类型
let result = type(_this.promiseResult)
if (result instanceof Promise) {
result.then(
(value) => {
resolve(value)
},
(reason) => {
reject(reason)
}
)
} else {
resolve(result)
}
} catch (error) {
reject(error)
}
}
//判断状态,决定执行成功或失败回调
if (_this.promiseState === 'fulfilled') {
callback(onResolved)
}
if (_this.promiseState === 'rejected') {
callback(onRejected)
}
//如果是异步,那就要把then的回调保存起来,等状态改变时再调用对应回调
if (_this.promiseState === 'pending') {
_this.callback.push({
onResolved: () => {
callback(onResolved)
},
onRejected: () => {
callback(onRejected)
}
})
}
})
}
//添加catch
catch (onRejected) {
return this.then(undefined, onRejected)
}
//添加resolve方法
static resolve (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
value => {
resolve(value)
},
reason => {
reject(reason)
})
} else {
resolve(value)
}
})
}
//添加reject方法
static reject (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加all方法
static all (promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
promises.forEach((item, index) => {
item.then(
value => {
count++,
arr[index] = value
if (index === promises.length - 1) {
resolve(arr)
}
},
reason => {
reject(reason)
}
)
});
})
}
//添加race方法
static race (promises) {
return new Promise((resolve, reject) => {
promises.forEach(item => {
item.then(
value => {
resolve(value)
},
reason => {
reject(reason)
}
)
});
})
}
}
})
async函数
- 定义函数
async function main(){}
- 返回值为
promise
对象 不return
,返回成功状态promise
对象,值为undefined
抛出错误
,返回失败状态的promise
对象,值为抛出的错误return 非promise对象值
,返回成功状态promise
对象,值为return
的非promise
对象值return promise对象
,返回的promise
对象的状态和值与return
的promise
对象
- 返回值为
await
关键字只能在async
函数中await
promise
对象promise
对象是成功状态,返回成功promise
对象的值promise
对象是失败状态,抛出错误,错误值也是失败promise
对象的值
await
其他- 返回其他
-async
与await
的应用
- 返回其他
const fs = require('fs')
const util = require('util')
//封装函数为promise对象
const myReadFile = util.promisify(fs.readFile)
async function main () {
let data1 = await myReadFile('./1.txt')
let data2 = await myReadFile('./2.txt')
let data3 = await myReadFile('./3.txt')
console.log(data1 + data2 + data3);
}
main()