与
-
同步模式:
后一个任务B等待前一个任务A结束后,再执行。任务的执行顺序和任务的排序顺序是一致的。 -
异步模式:
每一个任务有一个或多个回调函数,前一个任务A结束后,不是执行后一个任务B,而是执行任务A的回调函数。而后一个任务B是不等任务A结束就执行。任务的执行顺序,与任务的排序顺序不一致。
异步模式编程有四种方法:
- 回调函数(最基本的方法,把B写成A的回调函数)、
- 事件监听(为A绑定事件,当A发生某个事件,就执行B)、
- 发布/订阅
- Promise对象。
Promise的基本知识
1、三种状态
-
Pending:
进行中,刚创建一个Promise实例时,表示初始状态; -
resolved(fulfilled):
resolve方法调用的时候,表示操作成功,已经完成; -
Rejected:
reject方法调用的时候,表示操作失败;
2、两个过程
三种状态只能从pendeng-->resolved(fulfilled)
,或者pending-->rejected
,不能逆向转换,也不能在resolved(fulfilled)
和rejected
之间转换;并且一旦状态改变,就不会再改变,会一直保持这个结果。
//创建promise的实例
const promise = new Promise((resolve, reject) => {
//刚创建实例时的状态:pending
if ('异步操作成功') {
//调用resolve方法,状态从pending变为fulfilled
resolve();
} else {
//调用reject方法,状态从pending变为rejected
reject();
}
});
3、then()
用于绑定处理操作后的处理程序,分别指定fulfilled
状态和rejected
状态的回调函数,即它的参数是两个函数,第一个用于处理操作成功后的业务,第二个用于处理操作失败后的业务。
//then()
promise.then((res)=> {
//处理操作成功后的业务(即Promise对象的状态变为fullfilled时调用)
},(error)=> {
//处理操作失败后的业务(即Promise对象的状态变为rejected时调用)
});
4、catch()
用于处理操作异常的程序,catch()
只接受一个参数
//catch()
promise.catch((error)=> {
//处理操作失败后的业务
});
一般来说,建议不要在then()里面定义rejected状态的回调函数,而是将then()用于处理操作成功,将catch()用于处理操作异常。因为这样做可以捕获then()执行中的错误,也更接近同步中try/catch的写法:
//try-catch
// bad
promise.then((res)=> {
//处理操作成功后的业务
}, (error)=> {
//处理操作失败后的业务
});
// good
promise.then((res)=> {
//处理操作成功后的业务
})
.catch((error)=> {
//处理操作失败后的业务
});
5、all()
接受一个数组作为参数,数组的元素是Promise实例对象。只有当参数中的实例对象的状态都为fulfilled
时,Promise.all( )才会有返回。
//创建实例promise1
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve('promise1操作成功');
console.log('1')
}, 3000);
});
//创建实例promise1
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve('promise2操作成功');
console.log('2')
}, 1000);
});
Promise.all([promise1, promise2]).then((result) => {
console.log(result);
});
// 2
// 1
// ['promise2操作成功','promise1操作成功']
6 race()
和all()的参数一样,参数中的promise实例,只要有一个状态发生变化(不管是成功fulfilled还是异常rejected),它就会有返回,其他实例中再发生变化,它也不管了。
//创建实例promise1
const promise1 = new Promise((resolve) => {
setTimeout(() => {
resolve('promise1操作成功');
console.log('1')
}, 3000);
});
//创建实例promise1
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('promise1操作失败');
console.log('2')
}, 1000);
});
Promise.race([promise1, promise2])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
// 2
// promise1操作失败
// 1
实例
//------请求A 开始---------
$.ajax({
success: function (res1) {
//------请求B 开始----
$.ajax({
success: function (res2) {
//----请求C 开始---
$.ajax({
success: function (res3) {
}
});
//---请求C 结束---
}
});
//------请求B 结束-----
}
});
//------请求A 结束---------
在请求A的success后,请求B发送请求,在请求B 的success后,请求C发送请求。请求C结束后,再向上到请求B结束,请求B结束后,再向上到请求A结束。
const promise = new Promise((resolve, reject) => {
if (true) {
//调用操作成功方法
resolve('操作成功');
} else {
//调用操作异常方法
reject('操作异常');
}
});
//then处理操作成功,catch处理操作异常
promise.then(requestA)
.then(requestB)
.then(requestC)
.catch(requestError);
function requestA() {
console.log('请求A成功');
return '下一个是请求B';
}
function requestB(res) {
console.log('上一步的结果:' + res);
console.log('请求B成功');
return '下一个是请求C';
}
function requestC(res) {
console.log('上一步的结果:' + res);
console.log('请求C成功');
}
function requestError() {
console.log('请求失败');
}
// 请求A成功
// 上一步的结果:下一个是请求B
// 请求B成功
// 上一步的结果:下一个是请求C
// 请求C成功
看出请求C依赖请求B的结果,请求B依赖请求A的结果,在请求A中是使用了return将需要的数据返回,传递给下一个then()中的请求B,实现了参数的传递。同理,请求B中也是用了return,将参数传递给了请求C。