<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ES6--Promise</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<script>
/*
ES6--Promise
*/
/*
1.Promise诞生原因
2.Promise生命周期
3.Promise基本用法
3.1 then()函数
3.2 catch()函数
3.3 Promise.all()函数
3.4 Promise.race()函数
3.5 Promise.resolve()函数
3.6 Promise.reject()函数
4.运用
*/
// 1.Promise诞生原因
/*
在promise以前,在处理多个请求且需依赖另一个请求结果时,常用ajax回调实现。
但是多次回调会形成‘回调地狱’。
‘回调地狱’:
代码臃肿,可读性茶。
代码耦合度高,可维护性差,难以复用。
回调函数时匿名函数,不方便调试。
*/
// $.ajax({
// url:"url",
// success:function(res){
// console.log('ajax结果111',res)
// $.ajax({
// url:"url",
// success:function(res){
// console.log('ajax结果2222',res)
// $.ajax({
// url:"url",
// success:function(res){
// console.log('ajax结果2222',res)
// $.ajax({
// url:"url",
// success:function(res){
// console.log('ajax结果2222',res)
// }
// })
// }
// })
// }
// })
// }
// })
// 2.Promise生命周期
/*
每一个promise都有3种状态,即pending(进行中)、fulfilled(已成功)和rejected(已失败)。
promise在创建时处于pending状态,成功时转为fulfilled,失败时转为rejected。
状态一旦改变就不能在改变,状态改变一次后得到的就是promise的最终状态。
*/
// 3.Promise基本用法
/*
promise本身是一个构造函数,可以通过new操作符生成promise的实例。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve方法和reject方法。
如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);
如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。
*/
var promise = new Promise(function(resolve, reject) {
/* 异步操作成功 */
if (true){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(value) {
// failure
});
// 3.1 then()函数
/*
promise在原型属性上添加了一个then()函数,表示在promise实例状态改变是执行的回调函数。
then() 方法返回一个 Promise (en-US)。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
注意:如果忽略针对某个状态的回调函数参数,或者提供非函数 (nonfunction) 参数,
那么 then 方法将会丢失关于该状态的回调函数信息,但是并不会产生错误。
如果调用 then 的 Promise 的状态(fulfillment 或 rejection)发生改变,
但是 then 中并没有关于这种状态的回调函数,那么 then 将创建一个没有经过回调函数处理的新 Promise 对象,
这个新 Promise 只是简单地接受调用这个 then 的原 Promise 的终态作为它的终态。
语法:
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
参数:
onFulfilled 可选
当 Promise 变成接受状态(fulfilled)时调用的函数。
该函数有一个参数,即接受的最终结果(the fulfillment value)。
如果该参数不是函数,则会在内部被替换为 (x) => x,即原样返回 promise 最终结果的函数
onRejected 可选
当 Promise 变成拒绝状态(rejected)时调用的函数。
该函数有一个参数,即拒绝的原因(rejection reason)。
如果该参数不是函数,则会在内部被替换为一个 "Thrower" 函数 (it throws an error it received as argument)。
*/
const promis=new Promise((resolve,reject)=>{
resolve('1');
})
//then链式调用
promis.then((result)=>{
console.log(result);//1
return 2;
}).then((result)=>{
console.log(result);//2
})
// 3.2 catch()函数
/*
虽然then()函数能解决rejected状态的promise的回调函数,但是并不推荐这么做,
而是交给catch()函数来处理。
catch() 方法返回一个Promise (en-US),并且处理拒绝的情况。
它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。
(事实上, calling obj.catch(onRejected) 内部calls obj.then(undefined, onRejected)).
语法:
p.catch(onRejected);
p.catch(function(reason) {
// 拒绝
});
参数:
onRejected
当Promise 被rejected时,被调用的一个Function。 该函数拥有一个参数:
reason rejection 的原因。
如果 onRejected 抛出一个错误或返回一个本身失败的 Promise ,
通过 catch() 返回的Promise 被rejected;否则,它将显示为成功(resolved)。
*/
const promis1=new Promise((resolve,reject)=>{
throw new Error('test');
});
promis1.catch((err)=>{
console.log(err);//Error: test
})
// 3.3 Promise.all()函数
/*
Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,
并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。
这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,
或者输入的iterable里没有promise了的时候。它的reject回调执行是,
只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
语法:
Promise.all(iterable);
参数:
iterable
一个可迭代对象,如 Array 或 String。
返回值:
如果传入的参数是一个空的可迭代对象,则返回一个已完成(already resolved)状态的 Promise。
如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved) Promise。
注意:Google Chrome 58 在这种情况下返回一个已完成(already resolved)状态的 Promise。
其它情况下返回一个处理中(pending)的Promise。这个返回的 promise 之后会在所有的 promise 都完成或有一个 promise 失败时异步地变为完成或失败。
*/
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
// 3.4 Promise.race()函数
/*
Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
语法:
Promise.race(iterable);
参数:
iterable
可迭代对象,类似Array。详见 iterable。
返回值:
一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,
就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。
*/
// 3.5 Promise.resolve()函数
/*
Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。
如果这个值是一个 promise ,那么将返回这个 promise ;
如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;
否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。
警告:不要在解析为自身的thenable 上调用Promise.resolve。
这将导致无限递归,因为它试图展平无限嵌套的promise。
语法:
Promise.resolve(value);
参数:
value
将被Promise对象解析的参数,也可以是一个Promise对象,或者是一个thenable。
返回值:
返回一个带着给定值解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。
*/
// 3.6 Promise.reject()函数
/*
Promise.reject()方法返回一个带有拒绝原因的Promise对象。
语法:
Promise.reject(reason);
参数:
reason
表示Promise被拒绝的原因。
返回值:
一个给定原因了的被拒绝的 Promise。
*/
// 4.运用
//4.1 同一个Promise中,resolve()函数和reject()函数先后执行
/*多次执行resolve()函数和reject()函数*/
const promis2=new Promise((resolve,reject)=>{
resolve('success1');
reject('err');
resolve('success2');
});
promis2.then((res)=>{
console.log('then:',res);//then: success1
})
.catch((err)=>{
console.log('catch:',err);
});
/*
结果:只输出then: success1
总结:
一个Promis只有一次状态改变,当执行了resolve()函数后,后续的resolve()函数和reject()函数都不会执行,然后直接进入then()。
*/
//4.2 两种方法处理rejected状态的Promise
/*
rejected状态的Promise有两种处理方法,一种是then()第二参数,一种是catch()函数。
*/
Promise.resolve()
.then((res)=>{
throw new Error('err');
},(err)=>{
console.log('faill:',e);
})
.catch((err)=>{
console.log('faill2:',err)//faill2: Error: err
});
/*
结果:只输出faill2: Error: err
总结:
虽然这两种方法都能处理Promise状态变为rejected时的回调,但是then()函数的第二个函数却不能捕获第一个函数中抛出的异常,而catch()函数能够。
这也是推荐使用catch()函数的原因。
*/
</script>
</body>
</html>