-
1.Promise是什么?
-
Promise
是一个构造函数, 用于创建Promise对象- Promise对象:可以理解为一个处理异步操作的容器
-
-
2.Promise作用:解决回调地狱
- 回调地狱:异步回调 层层嵌套
Promise特点介绍(原理篇)
promise本质 不是控制 异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序
promise本身只是一个容器,真正异步的是它的两个回调resolve()和reject()
* 1.promise对象有三个状态.
a. pending(进行中)
b. fulfilled(已成功)
c. rejected(已失败)
* 2.Promise对象的状态改变, 只有两种可能:
a. 从pending变为fulfilled
* 此时应该执行 resolve();
b. 从pending变为rejected。
* 此时应该执行 reject();
* 3.promise在创建对象的时候,里面的代码会立即执行.
a. promise创建时,里面的代码还是异步无序操作
b. promise的原理是,利用then方法将异步操作的结果 按照顺序执行
总结: **不要在创建promise的时候去处理异步操作结果,而应该通过 then() 方法来处理 **
4.promise解决回调地狱原理 : 在then方法中返回一个promise对象
在上一个promise的then方法中,返回下一个promise
下面一篇代码可以更好的了解Promise
//(1) 创建三个异步操作 promise
//读取文件A
const p1 = new Promise((resolve,reject)=>{
//读文件
fs.readFile('./data/a.txt','utf8',(err,data)=>{
if(err == null){
//成功
resolve(data);
}else {
//失败
reject(err);
}
});
});
//读取文件B
const p2 = new Promise((resolve,reject)=>{
//读文件
fs.readFile('./data/b.txt','utf8',(err,data)=>{
if(err == null){
//成功
resolve(data);
}else {
//失败
reject(err);
}
});
});
//读取文件C
const p3 = new Promise((resolve,reject)=>{
//读文件
fs.readFile('./data/c.txt','utf8',(err,data)=>{
if(err == null){
//成功
resolve(data);
}else {
//失败
reject(err);
}
});
});
// (2)按照顺序处理异步操作结果
p1.then((data)=>{//第一个异步结果
console.log(data);
return p2;//返回下一个promise
}).then((data)=>{ // 第二个异步结果 (由于p1.then方法返回的是p2,而p2也有自己的then,所以可以继续调用p2的then方法)
console.log(data);
return p3;//返回下一个promise
}).then((data)=>{ // 第三个异步结果
console.log(data);
});
axios底层基于promise
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.axios() : 返回值是promise实例对象
2.axios() : 底层是基于promise技术封装xhr
*/
//手写axios底层原理
function axios(obj){
return new Promise((resolve,reject)=>{
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//(2).设置请求方法和地址ii
//get请求的数据直接添加在url的后面 格式是 url?key=value
xhr.open('get', obj.url )
//(3).发送请求
xhr.send()
//(4).注册回调函数
xhr.onload = function() {
resolve( JSON.parse(xhr.responseText) )
}
})
}
// const p1 = axios()// axios()方法本质是创建promise对象并返回
// console.log( p1 )//promise实例对象
Promise.all( [axios({url:'https://autumnfish.cn/api/joke/list?num=10'}) , axios({url:'https://autumnfish.cn/fruitApi/fruits'})] ).then(res=>{
console.log(res)
})
</script>
</body>
</html>
ES6异步函数async与await
异步函数async相当于是promise语法的 “高级写法”
ES2017中引入的更为高级的异步处理机制,async函数,可以让异步的处理变的更加便捷
-
(1)函数前面使用
async修饰 -
(2) 函数内部,promise操作使用
await修饰await后面是promise对象, 左侧的返回值就是这个promise对象的then方法中的结果await必须要写在async修饰的函数中,不能单独使用,否则程序会报错
以下代码可以看看Promise和异步函数async的区别
/*
promise实例对象的catch方法 : 用于捕获异步操作的错误信息
*/
//1.封装一个函数 : 根据文件名生成 文件读取的promise
function getPromise(fileName) {
let p = new Promise((resolve, reject) => {
//读文件
fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {
if (err == null) {
//成功
resolve(data);
} else {
//失败
reject(err);
}
});
});
return p;
};
//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.
// async和await异步函数 : 这两个关键字只能用于函数, 所以用的时候一定要放在函数里面用
/*
async关键字: 修饰函数。 表示这个函数内部有异步操作。
await关键字: 等待异步执行完毕。
(1)await只能用于被async修饰的函数中。
只有当await后面的异步操作执行完毕后,才会继续执行后面代码
(2)await 后面 只能是promise对象
*/
const readFile = async () => {
let data1 = await getPromise('a')
console.log(data1)
let data2 = await getPromise('b')
console.log(data2)
//async异步函数的错误信息要用try-catch来捕捉
try {
let data3 = await getPromise('c')
console.log(data3)
} catch (err) {
console.log(err)
}
}
readFile()