本次主要讲解Promise相关内容
Promise优点:
可以解决回调地狱问题(即函数一层层调用)
Promise初体验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
//随机数
const rd = Math.floor(Math.random() * 10)
//resolve 表示 解决 函数类型数据 (成功时候调用)
//reject 表示 拒绝 函数类型数据 (失败时调用)
const p = new Promise(((resolve, reject) => {
if (rd > 5) {
resolve() //将promise对象的状态设置为成功
} else {
reject() //将promise对象的状态设置为失败
}
}))
//调用then方法
//第一个函数是函数成功时的回调,第二个函数是函数失败时的回调
//也就是说第一个回调对应resolve,第二个回调对应reject
p.then(() => {
//成功时回调
console.log("你的数字大于5")
}, () => {
//失败时回调
console.log("你的数字小于或等于5")
})
</script>
</body>
</html>
使用Promise格式来操作nodejs的fs模块
const fs = require("fs");
const p = new Promise((resolve, reject) => {
fs.readFile("./test.txt", ((err, data) => {
if (err) reject(err)
//如果成功
resolve(data.toString())
}))
})
//调用then方法来对数据进行处理
p.then((data) => {
//成功时调用
console.log(data)
}, (err) => {
//失败时调用
console.log(err)
})
Promise.resolve
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
var promise = Promise.resolve(11);
console.log(promise)
</script>
</body>
</html>
Promise.reject
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
var promise = Promise.reject(11);
console.log(promise)
</script>
</body>
</html>
Promise.all
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
也就是说只有3个promise都为resolve时,他才会成功
如果有一个为reject,那就会失败
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let p1 = new Promise((resolve, reject) => {
resolve("ok")
})
let p2 = Promise.resolve("success")
let p3 = Promise.resolve("Yes")
var promise = Promise.all([p1, p2, p3]);
console.log(promise)
</script>
</body>
</html>
Promise.race()
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let p1 = Promise.resolve("ok")
let p2 = Promise.reject("ok")
//如果第一个promise为resolve,则race状态也为成功,如果第一个promise为reject,则race状态为失败
const promise = Promise.race([p1, p2]);
console.log(promise)
</script>
</body>
</html>
Promise串联多个任务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let p = new Promise((resolve, reject) => {
resolve("ok")
})
p.then(value => {
//返回一个新的Promise对象
return new Promise((resolve, reject) => {
resolve("success")
})
}).then(value => {
console.log(value) //输出success
})
</script>
</body>
</html>
async函数
1.async函数的返回结果是一个promise对象
2.promise对象的结果由async函数执行的返回值决定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
async function test() {
return new Promise(((resolve, reject) => {
//当promise的状态为成功时,async函数的返回值也为成功
// resolve("ok")
//当promise的状态为失败时,async函数的返回值也为失败
reject("err")
}))
}
let res = test()
console.log(res)
</script>
</body>
</html>
await表达式
1.await右侧的表达式一般为promise对象,但也可以是其他值
2.如果表达式是promise对象,await返回的是promise的成功值(resolve)
3.如果表达式是其他值,直接将此值作为await的返回值
注意:
1.await表达式必须要写在async函数中,但是async函数中可以不存在await表达式
2.如果await表达式的promise失败了,就会抛出异常,需要我们使用try...catch进行捕获处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
async function test() {
//创建一个promise对象
let p = new Promise((resolve, reject) => {
//这里返回的是成功状态
resolve("ok")
})
//1.右侧为promise对象的情况
let res = await p
console.log(res)
//2.右侧为其他类型数据时,await右侧是什么就会直接返回什么
let res2 = await 20
console.log(res2)
//3. 如果promise对象的状态为失败(reject),则需要我们进行try..catch异常捕获
let p2 = new Promise((resolve, reject) => {
reject("Error")
})
try {
//将await表达式放到try..catch中,在catch中可以获取promise失败状态时传来的信息
let res3 = await p2
} catch (e) {
//这里可以获取Promise对象的一个失败结果
console.log(e)
}
}
test()
</script>
</body>
</html>
async与await的结合使用(案例实践)
案例需求:
我们需要读取resource文件目录下的三个html文件的文件内容并将其输出
不使用Promise写法的实现
/*
* 我们需要读取resource文件目录下的三个html文件的文件内容并将其输出
* */
const fs=require("fs")
//这种情况就是我们文章一开始说的回调地狱情况,如果在要读三个文件,那就还得继续回调
//这样可读性不止差,还影响代码美观性.
fs.readFile("./resource/1.html",((err, data) => {
if(err) throw err
fs.readFile("./resource/2.html",((err1, data1) => {
if(err) throw err
fs.readFile("./resource/3.html",((err2, data2) => {
if(err) throw err
let contents=data+data1+data2
console.log(contents.toString())
}))
}))
}))
使用Promise写法的实现
/*
* 我们需要读取resource文件目录下的三个html文件的文件内容并将其输出
* */
const fs = require("fs")
const util = require("util")
//将fs.readFile转换为Promise格式
const readFilePromise = util.promisify(fs.readFile)
//async与await实现方式
async function test() {
//使用try..catch进行异常捕获,防止出现Promise对象的状态出现错误(reject)
try {
//如果promise返回的是成功状态,他的数据就会直接赋值给data1
let data1 = await readFilePromise("./resource/1.html")
let data2 = await readFilePromise("./resource/2.html")
let data3 = await readFilePromise("./resource/3.html")
console.log(data1 + data2 + data3)
} catch (e) {
console.log(e)
}
}
test()
无论从代码量还是美观程度,都是使用Promise实现的代码更优秀!
以上就是Promise相关的内容,欢迎各位评论教导,如果觉得文章还不错或者有什么地方不懂的,欢迎留言提问点赞🧡🤞🤞🤞🧡