Promise
Promise支持链式调用,可以解决回调地狱问题。
Promise简介
- Promise对象可以解决回调地狱的问题
- Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大
- Promise可以理解为一个容器,里面可以编写异步程序的代码
- 从语法上说,Promise 是一个对象,使用的使用需要
new
基本使用
-
promise 是一个对象,使用的时候需要new
-
在new promise的时候,必须要传递一个回调函数
-
返回了一个promise对象,里面包含一个方法 then()
-
回调函数中
- 回调函数中可以接收形参 callback 只要发现在回调函数中调用了 callback => 说明then方法被调用
- 写自己的业务逻辑-异步
- 异步操作完成了,调用callback函数
- callback被调用了;then方法才可以触发
const p1 = new Promise(function (callback) {
console.log('Prom被new啦,异步代码 settimeout');
setTimeout(() => {
console.log('数据返回了');
callback({ meta: '请求成功' })
}, 1000)
})
p1.then(res => {
console.log('p1 then方法输出了');
console.log(res);
})
完整使用
promise 内置了两种操作 成功 => resolve => 调用函数 => .then 失败 => reject => 调用函数 => .catch 调用了resolve, .then方法才会触发 调用了reject, .catch方法才会触发
const p1 = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
let result = { code: 200, mas: '接口没有权限' }
// 判断成功或失败
if (result.code === 200) {
resolve({ meta: '请求成功' })
} else {
reject({ meta: '请求失败' })
}
}, 1000)
})
p1.then(res => {
console.log('成功时调用');
console.log(res);
}).catch(err => {
console.log('失败时调用');
console.log(err);
})
三种状态
-
最初状态:pending,等待中,此时promise的结果为 undefined;
-
当 resolve(value) 调用时,达到最终状态之一:fulfilled,(成功的)完成,此时可以获取结果value
-
当 reject(error) 调用时,达到最终状态之一:rejected,失败,此时可以获取错误信息 error
当达到最终的 fulfilled 或 rejected 时,promise的状态就不会再改变了。
then的链式调用
关于 promise对象,可以一直then下去
then函数:1.创建promise对象;2.返回这个promise对象
如果在then函数中 return 数据回去,那么就可以在下一个then函数中获取到这个值
const p1 = new Promise(resolve => {
resolve()
})
p1.then(() => {
console.log(1);
return 22
})
.then(res => {
console.log(res);
return 33
})
.then(res => {const p1 = new Promise(resolve => {
resolve('我不调用,then不会触发')
})
p1.then(res => {
console.log(res);
const p2 = new Promise(resolve => {
setTimeout(() => {
resolve('返回的对象一定是promise')
}, 1000)
})
return p2
})
.then(res => {
console.log(res);
const p3 = new Promise(resolve => {
setTimeout(() => {
resolve('只有resolve调用了,then才会触发')
}, 1000)
})
return p3
})
.then(res => {
console.log(res);
})
console.log(res);
return 44
})
.then(res => {
console.log(res);
})
同步异步
new Promise是同步执行的
获取结果时(调用 resolve 触发 then方法时)是异步的
// 输出结果是:1;2;5;3
console.log(1);
// new promise 里面的代码是同步执行
const p1 = new Promise(resolve => {
console.log(2);
resolve(3)
})
// promise then 方式是异步的执行
p1.then(res => {
console.log(res);
})
console.log(5);
promise的封装
调用了resolve就可以触发then
then方法可以返回数据 -> promise对象
function sleep(num) {
const p2 = new Promise(resolve => {
setTimeout(() => {
resolve(num)
}, 1000)
})
return p2
}
const p1 = sleep(1)
p1.then(res => {
console.log(res);
return sleep(2)
})
.then(res => {
console.log(res);
return sleep(3)
})
.then(res => {
console.log(res);
return sleep(4)
})
.then(res => {
console.log(res);
sleep(res)
})
async 和 await 修饰符
用来解决异步回调的终极解决方案
-
async 用于修饰一个 function
- async 修饰的函数,总是返回一个 Promise 对象
- 函数内的返回值,将自动包装在 resolved 的 promise 中
-
await 只能出现在 async 函数内
- await 让 JS 引擎等待直到promise完成并返回结果
- 语法:let value = await promise对象; // 要先等待promise对象执行完毕,才能得到结果
- 由于await需要等待promise执行完毕,所以await会暂停函数的执行,但不会影响其他同步任务
-
对于错误处理,可以选择在async函数后面使用
.catch()或 在promise对象后使用.catch()
错误处理
function sleep(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (num !== 2) {
resolve(num)
} else {
reject('后端去吃饭了')
}
}, 1000)
})
}
// ---------------------- 通过 then 获取结果 --------------------------------
sleep(1)
.then(res => {
console.log(res);
return sleep(2)
})
.then(res => {
console.log(res);
return sleep(3)
})
.then(res => {
console.log(res);
return sleep(4)
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
// ---------------------- 通过 async/await 获取结果 ----------------------------
async function init() {
// try 里面放正常的代码
// 当有错误时,会执行catch里面的代码
try {
const res1 = await sleep(1)
console.log(res1);
const res2 = await sleep(2)
console.log(res2);
const res3 = await sleep(3)
console.log(res3);
const res4 = await sleep(4)
console.log(res4);
} catch (error) {
console.log(error);
}
}
init()