promise反复学习总结就会深刻 提高;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>再谈promise</title>
</head>
<body>
<script type="text/javascript">
/*
Promise 出现的原因: 例如ajax【根据第一个网络请求的结果,再去执行第二个网络请求】===> 此时造成回调地狱
后果:
1.代码臃肿
2.可读性差
3.耦合度过高,可维护性差
4.代码复用性差
5.容易滋生 bug
6.只能在回调里处理异常
什么是 Promise?
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
promise本身是同步的 promise的回调then/catch是异步的
async/await也是基于 Promise 实现的
async函数内部同步执行,await之间相当于.then。
async函数外部的调用异步执行
传统回调地狱版本:
请求1(function(请求结果1){
请求2(function(请求结果2){
请求3(function(请求结果3){
请求4(function(请求结果4){
请求5(function(请求结果5){
请求6(function(请求结果3){
...
})
})
})
})
})
})
promise版本:
new Promise(请求1)
.then(请求2(请求结果1))
.then(请求3(请求结果2))
.then(请求4(请求结果3))
.then(请求5(请求结果4))
.catch(处理异常(异常信息))
Promise常用的 API
Promise.prototype.then()
Promise.prototype.finally(): 不管 Promise 对象最后状态如何,都会执行的操作
Promise.all()
Promise.allSettled()
Promise.race(): Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
Promise.any(): 该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回
Promise.resolve()
Promise.reject(): 返回一个新的 Promise 实例,实例的状态为rejected
Promise.try()
Promise.prototype.catch()
Promise.try就是模拟try代码块,就像promise.catch模拟的是catch代码块
Promise有三种状态, pending , resolved , rejected , 只能从等待态转为其他两种状态;
每次调用then方法,都会返回一个新的promise;
promise支持链式调用,内部原理采用的是发布订阅模式;
一定谨记,一个 Promise 对象有三个状态,并且状态一旦改变,便不能再被更改为其他状态!!!
*/
// 首先初始化一个 Promise 对象,可以通过两种方式创建 Promise构造函数【new Promise()】接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数
// resolve函数的作用是: 将Promise对象的状态从【未完成】变为【成功】(即从 pending => resolved)
// reject函数的作用是: 将Promise对象的状态从【未完成】变为【失败】(即从 pending => rejected)
function fn(resolve, reject) {
console.log('返回promise对象')
// resolve(1)
}
// 方式一
const promise1 = new Promise(fn)
console.log(promise1) // Promise {<pending>} 若是fn加上 resolve(1) 则 状态变为 Promise {<fulfilled>: 1}
// 方式二
const promise2 = Promise.resolve(fn)
console.log(promise2) // Promise {<fulfilled>: ƒ}
/*****************Promise.any() 与 Promise.race() 和 Promise.all() 和 Promise.allSettled()********************/
// 只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态
// Promise.any()跟Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束
const q1 = new Promise((resolve, reject) => {
reject("失败");
});
const q2 = new Promise((resolve, reject) => {
setTimeout(resolve, 300, "后成功");
});
const q3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "先成功");
});
const q4 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最后成功");
});
Promise.any([q1, q2, q3]).then((res) => {
console.log(res); // 先成功
})
Promise.race([q2, q3, q4]).then((res) => {
console.log(res); // 先成功
})
Promise.all([q2, q3, q4]).then((res) => {
console.log(res); // ["后成功", "先成功", "最后成功"]
}).catch(e => console.log(e));
const resolved = Promise.resolve(1);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function(results) {
console.log(results); // [{status: 'fulfilled', value: 1},{status: 'rejected', reason: -1}]
});
// 总结
// Promise.any()即使第一个返回的 promise 是失败的,Promise.any() 依然使用第一个成功状态的 promise 来返回
// 这与使用首个(无论 rejected 还是 fullfiled)promise 来返回的 Promise.race() 相反
// Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝
// Promise.all(iterable) 方法返回一个 Promise 实例只要有其中一个promise实例是rejected,就会直接走catch方法,并且catch中只会返回第一个变成rejected的promise的错误
// Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理
// Promise.all()无法确定所有请求都结束 Promise.allSettled()就很容易
/****************************Promise.resolve()**************************************/
// 需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用
const r1 = Promise.resolve('aa')
console.log(r1, 'r1') // Promise {<fulfilled>: "aa"} "r1"
// 等价于
const r2 = new Promise(resolve => resolve('aa'))
console.log(r2, 'r2') // Promise {<fulfilled>: "aa"} "r2"
// Promise.resolve()参数的四种情况
// 1.参数是一个 Promise 实例
// 如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例
// 2.参数是一个thenable对象
let thenable = {
then: function(resolve, reject) {
resolve(666);
}
};
let promise = Promise.resolve(thenable);
promise.then(function(res) {
console.log(res, 'res'); // 666
});
// 3.参数不是具有then()方法的对象,或根本就不是对象
const p = Promise.resolve('Hello world');
p.then(function(res) {
console.log(res) // Hello world
});
// 4.不带有任何参数
setTimeout(function() {
console.log('3');
}, 0);
Promise.resolve().then(function() {
console.log('2');
});
console.log('1');
// 输出的顺序为 1 2 3
/****************************Promise.reject()**************************************/
// Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数
const p1 = Promise.reject('出错了'); // Uncaught (in promise) 出错了
console.log(p1, 'p1') // Promise {<rejected>: "出错了"} "p1"
// 等同于
const p2 = new Promise((resolve, reject) => reject('出错了'))
p2.then(null, function(r) {
console.log(r, 'r') // 出错了 r
});
// 异步转同步
// 1.通过回调函数【回调函数就是将一个函数当作另一个主函数的参数来使用的函数】
function test2() {
console.log('执行了test2');
}
function test1(cb) { //(主函数)
console.log('执行了test1');
setTimeout(function() {
cb();
}, 1000);
}
// 执行
test1(test2);
// 2 async-await async/await的作用就是使异步操作以同步的方式去执行
// 一般情况下,async与await配合使用才能使异步操作同步化,await就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行
async function test() {
return '异步转同步'
}
console.log(test()); //Promise { '异步转同步' }
test().then(res => {
console.log(res, 'res'); // 异步转同步 'res'
})
function fn1() {
return new Promise(resolve => {
setTimeout(function() {
msg = 'wait me 3000';
resolve(msg)
}, 3000);
});
}
async function fn2() {
var result = await fn1();
console.log(result);
}
fn2();
// 使用Promise
function fn3() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
msg = 'wait me 3000';
resolve(msg);
}, 3000);
})
}
fn3().then(data => {
console.log(data)
})
</script>
</body>
</html>
自己整理,请勿随意转载!!!!