Promise异步
ES6
Promise异步
1. 回调地狱(末日金字塔)
概念: 异步程序的回调函数嵌套
作用: 获取异步数据
缺点: 1.可复用性低 2.可阅读性差 3.可维护性差 4.可扩展性差
通俗来讲就是函数A执行回调函数B 回调函数B执行回调函数C 如此不断嵌套 形成一个不断右缩进的代码 这就是回调地狱(末日金字塔)
function fn(data, callback) {
console.log(data);
callback();
}
fn('a', () => {
fn('b', () => {
fn('c', () => {
...
})
})
})
2. Promise
概念: ES6提供了promise对象 为了解决传统异步方法(回调函数 + 事件)嵌套过多而产生回调地狱
特点: 1. 对象的状态不受外界影响 2. 任何时候Promise都 只有一种状态
2.1 Promise三种状态
- Pending 进行中
- Resolved 已完成
- 成功转到已完成状态 并执行resolve回调函数
- Rejected 已拒绝
- 失败转到已拒绝状态 并执行reject回调函数
2.2 基本用法
创建Promise构造函数的实例对象
//Promise构造函数接收一个函数作为参数 并且该函数又有两个参数 分别是resolve和reject 由JavaScript提供
var promise = new Promise(function(resolve, reject){
console.log('oh hello there')
})
Promise的then方法
两个参数: (成功回调,失败回调) 一般情况只需实现第一个参数 后面为可选参数
then(onFulfilled)
then(onFulfilled, onRejected)
// then表示当resolve(已完成)状态时 调用resolve方法 并将操作结果传递出去
// 这个then里面的箭头函数就是resolve resolve参数就是箭头函数的参数
var promise = new Promise(function(resolve, reject) {
resolve('hello');
})
promise.then(res => console.log(res))
// hello
then的返回值
- return 非Promise实例对象; 返回值为新Promise实例对象 没有结果 状态为resolve
- return Promise实例对象; 返回值为这个Promise实例对象
// then 的回调地狱
const p1 = new Promise((resolve, reject)=>{
resolve("hello");
})
const p2 = new Promise(function(resolve, reject){
resolve("p2的nononono")
});
p1.then(res => {console.log(res); p2.then(res => console.log(res))})
//利用then返回值的特性 使用链式编程将回调函数解耦
const p1 = new Promise((resolve, reject)=>{
resolve("hello");
})
const p2 = new Promise(function(resolve, reject){
resolve("p2的resolve")
});
p1.then(res => {
console.log(res);
return p2;
}).then(res => {
console.log(res);
})
// p1.then(res => {console.log(res); return p2;})返回值为p2实例对象
Promise的catch方法 (同then)
只有一个参数: (失败回调)
catch(onRejected);
// then表示当reject(已拒绝)状态时 调用reject方法 并将操作结果传递出去
// 这个then里面的箭头函数就是reject reject参数就是箭头函数的参数
var promise = new Promise(function(resolve, reject) {
reject('hello');
})
promise.catch(res => console.log(res))
// hello
catch的返回值
- return 非Promise实例对象; 返回值为新Promise实例对象 没有结果 状态为reject
- return Promise实例对象; 返回值为这个Promise实例对象
// catch 的回调地狱
const p1 = new Promise((resolve, reject)=>{
reject("world");
})
const p2 = new Promise(function(resolve, reject){
reject("p2的reject")
});
p1.catch(res => {console.log(res); p2.catch(res => console.log(res))})
//利用catch返回值的特性 使用链式编程将回调函数解耦
const p1 = new Promise((resolve, reject)=>{
reject("hello");
})
const p2 = new Promise(function(resolve, reject){
reject("p2的nononono")
});
p1.catch(res => {
console.log(res);
return p2;
}).catch(res => {
console.log(res);
})
// p1.catch(res => {console.log(res); return p2;})返回值为p2实例对象
Promise的finally方法
无论Promise最后是resolve还是reject 都会执行finally里的代码 参数与返回值同catch
2.3 Promise的方法
Promise.resolve()
返回值: resolve状态的Promise实例
参数 成功(resolve)状态下的数据
注意 禁止在创建一个成功状态调用自己的实例对象上用resolve() 这样会导致不断转到成功(resolve)状态 并不断调用自己 形成无限递归
let thenable = {
then: (resolve, reject) => {
resolve(thenable)// 成功状态调用自己
}
}
Promise.resolve(thenable)// 必定成功状态
// 这会造成一个死循环
Promise.reject()
返回值: reject状态的Promise实例
参数 失败(reject)状态下的数据
Promise.all()
用于将多个Promise实例包装成一个新的Promise实例
所有Promise实例成功才算成功参数 多个实例对象数组 [promise1, promise2, ...]
Promise.any()
用于将多个Promise实例包装成一个新的Promise实例
有一个Promise实例成功就算成功参数 多个实例对象数组 [promise1, promise2, ...]
Promise.race()
用于将多个Promise实例包装成一个新的Promise实例
赛跑机制 最先执行结束的子Promise实例决定状态参数 多个实例对象数组 [promise1, promise2, ...]
Promise.allSettled()
用于将多个Promise实例包装成一个新的Promise实例
所有子实例结束 新实例才会完成 包含所有子实例的状态参数 多个实例对象数组 [promise1, promise2, ...]
ES7异步解决方案 Async / Await
1. async关键字
添加在function关键字之前 表示这个函数是一个异步函数 函数执行结果自动返回一个成功(resolve)状态的Promise实例
异步函数 return 的是Promise实例成功状态时的数据
async function fn1() {
}
// Promise {<fulfilled>: undefined}
async function fn2() {
return 'hello'
}
// Promise {<fulfilled>: hello}
2. await关键字
这个关键字只能在async声明的异步函数中使用 等待一个异步执行结束并且返回成功(resolve)状态时的数据 将异步函数同步执行
async function fn(){
const res = await Promise.resolve("hello");
console.log(res); // hello
}
try...catch
异常捕获语句
try {
// tryCode - 尝试执行代码块 // 如果出错,抛出错误
} catch(error) {
// catchCode - 捕获错误的代码块
}finally {
// finallyCode - 无论 try / catch 结果如何都会执行的代码块
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现