Promise语法
- 一、回调地狱
- 二、Promise
- 三、async和await
- 四、fetch
一、回调地狱
- 当回调函数嵌套过多的时候出现的问题
- 没有可维护性和可读性
== 代码没有问题,不是错误的,只是不好进行后期维护
二、Promise
1、Promise的作用
- 主要用来解决异步回调地狱问题
- Promise是ES6中的语法,一般情况下都会把promise藏在封装的底层
- Promise(承诺)的三种状态
== pending 正在进行
== fulfilled 成功履行承诺
== rejected 没有遵守承诺 - 承诺的状态一旦发生改变,那么这个状态不可逆
2、创建Promise对象
Promise的构造函数必须传入一个函数作为参数,只有这个函数可以改变promise对象的状态,任何其他函数都没有资格去改变承诺状态。
我们通常使用异步程序去改变promise的规则。
Promise的函数参数有两个形参 fulfill,reject,分别表示异步操作成功后的回调函数和异步操作执行失败后的回调函数。其实这里的“成功”和“失败”来描述并不准确,按照标准来讲,fulfill是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。
promise的状态监听函数:
- then() :可以监听promise状态的改变
- catch() :可以监听promise状态改变为rejected
- finally() :只要状态改变了,就会进入这个函数之中
promise对象创建:
1.调用Promise构造函数
2.传入resolver函数
3.在resolver函数中定义状态改变的规则
new Promise(function(fulfill,reject)){
…
})
function getImags(src){
return new Promise(function(resolve,reject){
let img=new Image();
img.src=src;
img.onload=funtion(e){
resolve(img);
}
img.onerror=funtion(e){
reject("错误");
}
})
}
getImages("./img/1.jpg")
.then(function(img){
console.log(img);
},function(error){
console.log(error);
})
3、then
-
Promise必须提供一个then方法,用来访问中间值、最终返回值以及失败的原因。
-
then的参数:
最基本的then方法接收两个函数参数 Promise.then(成功执行的函数,失败执行的函数),对应于状态变化到fulfilled和rejected的函数调用。
一般情况下我们都只会传递一个参数,表示成功。 -
then的返回值
没有在回调函数中写return的情况下,返回为promise对象;
在回调函数之中写了return 新的promise的情况下,返回值为新的promise对象。
默认情况下 promise.then 返回的是一个新的promise对象,但是这个对象和then的调用对象状态改变时机一致;
then的使用注意事项 : 使用then之后可以去返回一个新的promsie对象用以连缀;
- then方法中回调函数的参数,就是fullfill调用时传入的实参
var p=new Promise(function(fulfill){
fullfill("hello promise");
})
p.then(function(res){
console.log(res); //res就是promise中fulfill函数传入的实参
})
4、catch
catch方法带一个参数,为失败时的回调。
catch 就是做错误处理用的。
其实.catch方法就是.then(undefined,rejected)的简化版
getImage("./img/1.png")
.then(function(img){
console.log(img);
})
.catch(function(error){
console.log(error);
})
5、finally
finally方法,状态的改变不做数据的处理。
var p=new Promise(function(fulfill){
fulfill("hello world");
})
p.finally(function(res){
//这里的res是undefined,他不做数据的处理
console.log(res);
})
6、链式异步
Promise.then是成功的回调,只要then里面再次return一个新的Promise对象,那么可以在then后面继续then,形成链式异步
getImage("./img/1.jpg").then(function(img){
document.body.appendChild(img);
return getImage("./img/2.jpg");
}).then(function(img){
document.body.appendChild(img);
return getImage("./img/3.jpg");
}).then(function(img){
document.body.appendChild(img);
return getImage("./img/4.jpg");
}).then(function(img){
document.body.appendChild(img);
})
7、all的使用
all用于全部异步完成统一执行
Promise.all([getImage("./img/1.jpg"),getImage("./img/2.jpg"),getImage("./img/3.jpg"),getImage("./img/4.jpg")])
.then(function(imgarr){
//这里可以根据异步调用的先后顺序获取到一个数组imgarr,
//数组中就是所有异步传入的参数
imgarr.forEach(function(item){
document.body.appendChild(item);
})
})
8、race的使用
race用于同时执行多个异步,如果哪个先完成就直接结束,处理这个先完成的
race就是比赛的意思,这里只返回最先加载的数据
Promise.race([getImage("./img/1.jpg"),getImage("./img/2.jpg"),getImage("./img/3.jpg"),getImage("./img/4.jpg")])
.then(function(img){
document.body.appendChild(img);
})
三、async和await
1、async
async用来定义函数的关键字,表示函数是异步执行的,在函数中使用return返回内容时,其实执行函数就是返回一个Promise,我们可以使用Promise来调用这个异步函数返回的值。
async function fn1(){
let a=1;
return a;
}
fn1().then(function(a){
console.log(a);
})
2、await 只能使用在async定义的函数中;等待promise对象状态变为成功,并且把then里面的参数返回出来。
实际是在异步函数中,调用外部的异步函数时,需要同步执行各个异步函数,那么就可以使用await调用,将返回的值赋予一个变量或者执行内容,当这个异步执行完成后才执行下一个异步。
async function fn1(){
return "hellow";
}
async function fn2(){
let s=await fn1();
s+=" world";
console.log(s);
}
fn2();
注意:async 定义的函数返回值是promise对象;但async只是返回值是promise对象,不能替代promise对象的构造。
四、fetch
1、fetch
- fetch: xhr请求发送工具
- fetch是属于浏览器的高级封装
- fetch完全不兼容IE,即PC端开发不能使用
- fetch最大的优势是不用加载额外的代码
2、fetch的参数
- fetch(url,options)
- 返回值是promise
使用fetch向服务器请求数据
async funtion load(){
//返回响应的对象
let reoponse=await fetch("./text.php");
//处理响应对象,决定响应数据的类型
let data=await response.text();
//response.text() -->决定响应数据类型为文本
//response.json() -->决定响应数据类型为json格式
console.log(data);
}