目录
4..then(),.catch()返回的新 promise 的结果和状态由什么决定
一、promise的操作
0.初体验-promise的使用
(1)抽奖案列,用一下promise
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>初体验</title>
</head>
<body>
<div class="container">
<h2>Promise 初体验</h2>
<button class="btn btn-primary" id="btn">点击抽奖</button>
</div>
</body>
<script>
function rand(m, n) {
return Math.ceil(Math.random() * (n - m + 1)) + m - 1
}
const btn = document.querySelector('#btn');
btn.addEventListener('click', function () {
// setTimeout(() => {
// let n = rand(1, 100);
// if (n <= 30) {
// alert('您未中奖')
// } else {
// alert('恭喜您中奖了')
// }
// }, 1000)
// promise里面传一个回调函数
// 参数为resolve--解决--函数类型数据和reject--拒绝--函数类型数据
//
const p = new Promise((resolve, reject) => {
// 异步操作放到回调函数里
setTimeout(() => {
let n = rand(1, 100);
if (n <= 30) {
// 成功调用这个函数
resolve(n) //将promise状态设置为成功
} else {
// 失败调用这个函数
reject(n) //将promise状态设置为失败
}
console.log(n);
}, 1000)
})
// 状态成功执行第一个回调函数,失败执行第二个回调函数
p.then((value) => {
alert('恭喜您中奖了,中将号码为' + value)
}, (reason) => {
alert('您未中奖,号码为' + reason)
})
})
</script>
(2)promise进行文件操作:
const { log } = require('console')
const fs = require('fs')
// 回调形式
// fs.readFile('./resource/context.txt', (err, data) => {
// if (err) throw error
// console.log(data.toString())
// }),
const p = new Promise((resolve, reject) => {
fs.readFile('./resource/context.txt', (err, data) => {
// 如果失败调用 reject函数 并传入err参数
if (err) reject(err)
// 如果成功调用 resolve函数 并传入data参数
resolve(data)
})
})
p.then((value) => {
console.log(value.toString())
}, (err) => {
console.log(err)
})
(3)使用promise发送ajax请求
要熟练掌握发送原生ajax请求
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container"></div>
<h2>Promise封装ajax</h2>
<button class="btn btn-primary" id="btn">发送ajax请求</button>
</div>
</body>
<script>
const btn = document.querySelector('#btn')
btn.addEventListener('click', function () {
const p = new Promise((resolve, reject) => {
// 1.创建对象
const xhr = new XMLHttpRequest()
// 2.初始化
xhr.open('GET', 'https://www.baidu.com/')
// 3.发送请求
xhr.send()
// 4.处理响应结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
p.then(response => {
console.log(response)
}, status => {
console.log(status)
})
})
</script>
1.Promise封装fs读取文件操作
封装一个函数myReadFile 读取文件内容
参数:path 文件路径
返回:promise对象
function myReadFile(path) {
return new Promise((resolve, reject) => {
require('fs').readFile(path, (err, data) => {
if (err) reject(err)
resolve(data)
})
})
}
// 返回的是一个promise对象所以可以then
myReadFile('./resource/context.txt').then(value => {
console.log(value.toString())
}, reason => {
console.log(reason)
})
util.promisify()函数封装读取文件操作
// 引入util
const util = require('util')
// 引入fs
const fs = require('fs');
// 相当于把fs.readFile函数转为了promise风格
// 前面的参数你自己传,后面的回调函数代码固定,自动给你写好了
// 是err优先,并且参数都给你传好了
// 所以能转成promise风格的函数也不多
// 函数返回promise
let myReadFile = util.promisify(fs.readFile);
myReadFile('./resource/context.txt').then(value => {
console.log(value.toString())
}, reason => {
console.log(reason)
})
2.Promise封装原生ajax GET请求
<script>
function sendAjax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
}
sendAjax('http://api.apiopen.top/getJok').then(value => {
console.log(value.toString())
}, reason => {
console.log(reason)
})
</script>
3.Promise实例对象的两个属性
(1)状态属性PromiseState
初始PromiseState的值为pending未决定的,之后成功就是pending变为resolved(或fullfilled),失败就变成了rejected。且一个promise对象只能改变一次,不可能从resolved变到rejected,也不可能从rejected变为resolved。
(2)结果值属性PromiseResult
保存着异步任务成功或失败的结果,只有resolve和reject接收到的值决定它的值。
4.Promise的工作流程
5.Promise的API
(1)then和catch
(2)Promise.resolve (value)
resolve属于函数对象而不是实例对象
<script>
//
let p1 = Promise.resolve(521);
//如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象
//如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
let p2 = Promise.resolve(new Promise((resolve, reject) => {
// resolve('OK');
reject('Error');
}));
// console.log(p2);
p2.catch(reason => {
console.log(reason);
})
</script>
(3)Promise.reject(reason)
reason: 失败的原因
无论value传入什么值,返回的都是失败的promise对象
(4)Promise.all([p1,p2,p3])
传入一个数组,若p1、p2、p3都是一个成功的promise对象则函数返回一个新的成功的promise对象,且属性值为p1、p2、p3属性值组成的数组。只要有一个失败返回的就是一个失败的promise对象,属性值为失败的那个promise的属性值。若有多个失败呢?只会有一个失败,后面的不执行。
成功:
<script>
let p1 = new Promise((resolve, reject) => {
resolve('OK')
})
let p2 = Promise.resolve('yes')
let p3 = Promise.resolve('year')
console.log(Promise.all([p1, p2, p3]))
</script>
失败:
<script>
let p1 = new Promise((resolve, reject) => {
resolve('OK')
})
let p2 = Promise.reject('err')
let p3 = Promise.reject('shibai')
console.log(Promise.all([p1, p2, p3]))
</script>
(5)Promise.race([p1,p2,p3])
<script>
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000)
})
let p2 = Promise.reject('err')
let p3 = Promise.reject('shibai')
console.log(Promise.race([p1, p2, p3]))
</script>
二、一些关键问题
1.如何修改promise对象的状态
2.能否执行多个回调
<script>
let p = new Promise((resolve, reject) => {
resolve('ok')
})
p.then(value => {
console.log('执行1')
})
p.then(value => {
console.log('执行2')
})
// 结果俩个都执行
</script>
3.改变promise状态和指定回调的区别
指定回调就是then,指定和执行不一样。
先指定回调再改变状态再执行回调函数
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 1000)
})
p.then(value => {
console.log('执行1')
}, reason => {
})
</script>
4..then(),.catch()返回的新 promise 的结果和状态由什么决定
let p = new Promise((resolve, reject) => {
resolve('ok')
})
let result = p.then(value => {
// throw 'Error'
// return 520
return new Promise((resolve, reject) => {
resolve('success')
})
}, reason => {
})
console.log(result)



5.串联多个任务(链式调用)
let p = new Promise((resolve, reject) => {
resolve('ok')
})
let result = p.then(value => {
// throw 'Error'
// return 520
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value => {
console.log(value) //上一个是新promise对象调用then,value为success
}).then(value => {
console.log(value) //输出为undefined,因为上一个then返回新的promise,没有返回值,所以没属性值,根据规则是状态是成功
})
console.log(result)
6.异常穿透
let p = new Promise((resolve, reject) => {
resolve('ok')
})
let result = p.then(value => {
// throw 'Error'
// return 520
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value => {
console.log(111)
throw 'erroe'
}).then(value => {
console.log(222)
}).then(value => {
console.log(333)
}).catch(reason => {
console.warn(reason)
})
上面出现的错误会在最后的catch里被处理
7.中断Promise链
let p = new Promise((resolve, reject) => {
resolve('ok')
})
let result = p.then(value => {
// throw 'Error'
// return 520
return new Promise((resolve, reject) => {
resolve('success')
})
}).then(value => {
console.log(111)
}).then(value => {
console.log(222)
// return new Promise((resolve, reject) => { })
return new Promise(() => { })
}).then(value => {
console.log(333)
}).catch(reason => {
console.warn(reason)
})
三、手撕Promise
1.搭建整体结构
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./promise.js"></script>
</head>
<body>
<script>
let p = new Promise((resolve, reject) => {
resolve('OK')
});
p.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
</script>
</body>
</html>
在index.html中引入promise.js,并在其中设置两个函数,去覆盖原来的Promise和then,并且使用构造函数时要同步调用executor
function Promise(executor) {
// resolve函数
function resolve(data) {
}
// reject函数
function reject(data) {
}
// 同步调用函数执行器
executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {
}
2.resolve和reject的实现
注意里面resolve函数this指向window的两种解决办法
function Promise(executor) {
this.promiseState = 'pending'
this.promiseResult = null
const self = this
// resolve函数
//如果写成function,里面的this指向为window,所以写成箭头函数
// 或者在外面用self保存好this
resolve = (data) => {
// 1.功能:修改对象的状态promiseState
this.promiseState = 'fulfilled'
// 2.设置对象结果值(promiseResult)
this.promiseResult = data
}
// reject函数
function reject(data) {
// 1.功能:修改对象的状态promiseState
self.promiseState = 'rejected'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
}
// 同步调用函数执行器
executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {
}
3.throw抛出错误改变状态
throw抛出错误,用catch接到仔调用reject改变promise状态和属性值
try {
// 同步调用函数执行器
executor(resolve, reject)
} catch (e) {
// 修改promise状态为失败
reject(e)
}
4.状态一旦改变就不能再变
只需在里面加个promiseState的判断
// resolve函数
//如果写成function,里面的this指向为window,所以写成箭头函数
// 或者在外面用self保存好this
resolve = (data) => {
// 判断状态,只有pending的时候才能改变状态
// 即状态只能改变一次
if (this.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
this.promiseState = 'fulfilled'
// 2.设置对象结果值(promiseResult)
this.promiseResult = data
}
// reject函数
function reject(data) {
if (self.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
self.promiseState = 'rejected'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
}
5.then方法的初步封装
在then方法里加上两个判断并调用函数
if (this.promiseState === 'fulfilled') {
onResolved(this.promiseResult)
}
if (this.promiseState === 'rejected') {
onRejected(this.promiseResult)
}
5.异步任务回调的执行
异步执行,状态还没有改变,就去执行then了,而因为then没有对状态为pending的处理,所以执行不成功。我们需要在then加上对pending状态的处理。把函数保存到自己的callback上,然后在状态改变之后调用。
function Promise(executor) {
this.promiseState = 'pending'
this.promiseResult = null
this.callback = {}
const self = this
// resolve函数
//如果写成function,里面的this指向为window,所以写成箭头函数
// 或者在外面用self保存好this
resolve = (data) => {
// 判断状态,只有pending的时候才能改变状态
// 即状态只能改变一次
if (this.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
this.promiseState = 'fulfilled'
// 2.设置对象结果值(promiseResult)
this.promiseResult = data
// 状态改变了再去执行then的回调函数
if (this.callback.onResolved) {
this.callback.onResolved(data)
}
}
// reject函数
function reject(data) {
if (self.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
self.promiseState = 'rejected'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
// 状态改变了再去执行then的回调函数
if (self.callback.onRejected) {
self.callback.onRejected(data)
}
}
try {
// 同步调用函数执行器
executor(resolve, reject)
} catch (e) {
// 修改promise状态为失败
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
// 分别判断,调用这两个函数
if (this.promiseState === 'fulfilled') {
onResolved(this.promiseResult)
}
if (this.promiseState === 'rejected') {
onRejected(this.promiseResult)
}
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callback = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
6.执行多个then的回调
当在异步情况下执行多个then函数时,上面callback的保存方法会出现覆盖的情况,所以我们要把它改为数组,并且在状态改变后要用遍历的方式去调用
function Promise(executor) {
this.promiseState = 'pending'
this.promiseResult = null
this.callbacks = []
const self = this
// resolve函数
//如果写成function,里面的this指向为window,所以写成箭头函数
// 或者在外面用self保存好this
resolve = (data) => {
// 判断状态,只有pending的时候才能改变状态
// 即状态只能改变一次
if (this.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
this.promiseState = 'fulfilled'
// 2.设置对象结果值(promiseResult)
this.promiseResult = data
// 状态改变了再去执行then的回调函数
this.callbacks.forEach((item) => {
item.onResolved(data)
})
}
// reject函数
function reject(data) {
if (self.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
self.promiseState = 'rejected'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
// 状态改变了再去执行then的回调函数
self.callbacks.forEach((item) => {
item.onRejected(data)
})
}
try {
// 同步调用函数执行器
executor(resolve, reject)
} catch (e) {
// 修改promise状态为失败
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
// 分别判断,调用这两个函数
if (this.promiseState === 'fulfilled') {
onResolved(this.promiseResult)
}
if (this.promiseState === 'rejected') {
onRejected(this.promiseResult)
}
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
}
7.同步任务then方法的返回结果(难点)
实现then的返回值,它的值是一个Promise,其状态和结果值与回调函数返回的结果有关。如果回调函数返回的是promise,则then返回的promise的结果和状态和他一样。如果回调函数返回的不是promise,则then返回的promise的状态为成功,值是回调函数返回的值(没有就是undefined)。如果抛出异常,状态是异常,值为抛出的值。
<script>
let p = new Promise((resolve, reject) => {
resolve('chenggong')
// setTimeout(() => {
// reject('shibai')
// }, 1000)
// throw 'shibai'
});
// console.log(p)
const res = p.then(value => {
// console.log(value)
// 实现then的返回值,如果回调函数返回的是Promise则状态和结果与Promise有关
// return 'hello Promise'
return new Promise((resolve, reject) => {
reject('shibai')
})
// 抛出异常
// throw 'Fail'
}, reason => {
console.log(reason)
})
// p.then(value => {
// alert(value)
// }, reason => {
// alert(reason)
// })
// console.log(p)
console.log(res)
</script>
Promise.prototype.then = function (onResolved, onRejected) {
// then的返回值是一个promise
return new Promise((resolve, reject) => {
// 分别判断,调用这两个函数
if (this.promiseState === 'fulfilled') {
try {
// 获取回调函数的执行结果
let result = onResolved(this.promiseResult)
if (result instanceof Promise) {
// 如果是Promise对象,修改当前要返回的Promise的状态和值
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
// 结果对象状态为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.promiseState === 'rejected') {
onRejected(this.promiseResult)
}
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
})
}
8.异步任务then方法的返回结果(难点)
和同步差不多,关键是改callbacks里的函数
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('chenggong ')
}, 1000)
});
const res = p.then(value => {
throw 'Fail'
}, reason => {
console.log(reason)
})
console.log(res)
</script>
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callbacks.push({
onResolved: function () {
try {
// 执行成功的回调函数
let result = onResolved(self.promiseResult)
// 判断
if (result instanceof Promise) {
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
},
onRejected: function () {
let result = onRejected(self.promiseResult)
try {
// 判断
if (result instanceof Promise) {
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
})
}
})
9.then方法中封装重复代码
把判断是不是Promise的代码来修改then返回的promise的状态和值的那段代码进行封装
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
// then的返回值是一个promise
return new Promise((resolve, reject) => {
function callback(type) {
try {
// 获取回调函数的执行结果
let result = type(self.promiseResult)
if (result instanceof Promise) {
// 如果是Promise对象,修改当前要返回的Promise的状态和值
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
// 结果对象状态为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 分别判断,调用这两个函数
if (this.promiseState === 'fulfilled') {
callback(onResolved)
}
if (this.promiseState === 'rejected') {
callback(onRejected)
}
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
10.catch方法封装,异常穿透(难点)
下面那段代码写进then方法里,如果then没有传成功或失败的回调函数,就默认给你创建一个
// 添加catch方法
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
//写在then方法里
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = value => value
}
11.Promise.resolve方法封装
// 添加resolve方法
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}
12.Promise.reject方法封装
// 添加reject方法
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
13.Promise.all方法封装(难点)
// 返回一个promise,数组中的promise状态全为成功就是成功,
// 值是所有成功的promise组成的数组
// 添加all方法
// 返回一个promise,数组中的promise状态全为成功就是成功,
// 值是所有成功的promise组成的数组
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++
arr[i] = v
if (count === promises.length) {
resolve(arr)
}
}, r => {
this.reject(r)
})
}
})
}
14.Promise.race方法封装
// 添加race方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}
15.细节:then方法的回调是异步执行的
它是异步执行的,其它同步代码执行完它才会执行,只需要在resolve、reject函数还有下图两个位置加个定时器,即调用onResolved和onRejected函数的地方
执行结果应该是132
if (this.promiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.promiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
16.class版本
class Promise {
constructor(executor) {
this.promiseState = 'pending'
this.promiseResult = null
this.callbacks = []
const self = this
// resolve函数
//如果写成function,里面的this指向为window,所以写成箭头函数
// 或者在外面用self保存好this
function resolve(data) {
// 判断状态,只有pending的时候才能改变状态
// 即状态只能改变一次
if (self.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
self.promiseState = 'fulfilled'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
// 状态改变了再去执行then的回调函数
setTimeout(() => {
self.callbacks.forEach((item) => {
item.onResolved(data)
})
})
}
// reject函数
function reject(data) {
if (self.promiseState !== 'pending') return
// 1.功能:修改对象的状态promiseState
self.promiseState = 'rejected'
// 2.设置对象结果值(promiseResult)
self.promiseResult = data
// 状态改变了再去执行then的回调函数
setTimeout(() => {
self.callbacks.forEach((item) => {
item.onRejected(data)
})
})
}
try {
// 同步调用函数执行器
executor(resolve, reject)
} catch (e) {
// 修改promise状态为失败
reject(e)
}
}
then(onResolved, onRejected) {
const self = this
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
if (typeof onResolved !== 'function') {
onResolved = value => value
}
// then的返回值是一个promise
return new Promise((resolve, reject) => {
function callback(type) {
try {
// 获取回调函数的执行结果
let result = type(self.promiseResult)
if (result instanceof Promise) {
// 如果是Promise对象,修改当前要返回的Promise的状态和值
result.then(value => {
resolve(value)
}, reason => {
reject(reason)
})
} else {
// 结果对象状态为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
// 分别判断,调用这两个函数
if (this.promiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.promiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
});
}
if (this.promiseState === 'pending') {
// 要把回调函数保存到自身上。
this.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0
let arr = []
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
count++
arr[i] = v
if (count === promises.length) {
resolve(arr)
}
}, r => {
this.reject(r)
})
}
})
}
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
resolve(v)
}, r => {
reject(r)
})
}
})
}
}
四、async函数和await表达式(难点)
1.async函数
(1)函数的返回值是promise对象
(2)promise对象的结果由asynac函数执行的返回值决定
2.await表达式
(1)await右侧的表达式一般为promise对象,但也可以是其它值
(2)如果表达式是promise对象,await返回的是promise成功的值
(3)如果表达式是其它值,直接将此值作为await的返回值
注意
1.await必须写在async函数中,但async函数可以没有await
2.如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
<script>
async function main() {
// 1.右侧为promise的情况
let p = new Promise((resolve, reject) => {
reject('shibai')
})
try {
let res = await p
} catch (e) {
console.log(e)
}
let res2 = await 20
console.log(res2)
}
main()
</script>
3.async和await结合
可以避免回调地狱的问题
(1)文件读取
const fs = require('fs')
const util = require('util')
const myRead = util.promisify(fs.readFile)
async function main() {
try {
let data1 = await myRead('./resource/context.txt')
console.log(data1.toString())
} catch (e) {
console.log(e)
}
}
main()