ES6中的Promise
- 关于
new Promise()
- 解决了回调地狱
- Promise是构造函数,可以用new Promise()来创建对象
- Promise有状态(pedding,fulfilled,reject),如果状态pedding—>fulfilled/reject后,状态是不会再次改变的,还有个承诺的值
- 如果状态是fulfilled会执行then中的第一个方法,如果是reject会调用then中的第二个方法
- 如果new Promise()参数函数中返回的是Promise,那么返回的Promise决定了当前的Promise的状态和值,然后传递给then使用
- 我们在实际代码中一般用resolve来代替fulfilled
- resolve和reject不会导致函数的结束,而且他们都会放到最后执行,所以我们一般在其前面加上return
-
关于
.then
-
.then也会返回一个Promise对象,其返回的Promise状态和承诺的值是分情况讨论的
-
如果.then中参数函数中返回的不是一个Promise对象,那么其返回的是一个状态为resolve(成功)的Promise对象,承诺值是返回的值;如果没有返回值,那么也为成功的Promise对象,但是承诺值是undefined(从上图中可以看出)
-
如果.then中参数函数中返回的是一个Promise对象,那么返回的Promise对象的状态和承诺值决定了当前.then参数函数返回的Promise
-
如果.then没有参数函数来接受new Promise()参数函数的结果,在Promise规范中会自动忽略调当前then,所以会把new Promise()参数函数的结果供下一个then使用(如下图)
-
注意事项:.promise虽然是同步的,但是由于里面的代码有异步代码,所以依然不会阻塞进程,如下图:
下图中,设置了5秒,所以第一个Promise的状态会等待5秒而发生改变,由于Promise中有异步代码的,所以程序会继续往下执行。
当第一个Promise的状态变为resolve后,会调用第一个.then的第一个参数函数,由于fn()返回的不是一个函数,所以会忽略调当前.then,会把第一个Promise的结果给第二个.then
- 关于catch
- catch语法就像是.then方法中第二个参数函数中用来处理上一个失败的Promise的结果的语法糖的写法
- 如下图
ES8中的async和await
- async
- 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
- 抛出错误, 返回的结果是一个失败的 Promise
- 返回的结果如果是一个 Promise 对象,那么这个return 的Promise决定了async返回的Promise的状态和值
<script>
//async 函数
async function fn(){
// 返回一个字符串
// return '尚硅谷';
// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
// return;
//抛出错误, 返回的结果是一个失败的 Promise
// throw new Error('出错啦!');
//返回的结果如果是一个 Promise 对象
return new Promise((resolve, reject)=>{
resolve('成功的数据');
// reject("失败的错误");
});
}
const result = fn();
console.log(result)
//调用 then 方法
result.then(value => {
console.log(value);
}, reason => {
console.warn(reason);
})
</script>
- 关于await,必须在定义为async的函数中使用,可以直接接受到成功的Promise的结果,如果接受的是失败的Promise的结果,就要通过try,catch进行处理
- async和await结合使用会阻塞线程,变同步的,两者结合使用可以简化Promise的操作,直接获取Promise的值
<script>
//创建 promise 对象
const p = new Promise((resolve, reject) => {
// resolve("用户数据");
reject("失败啦!");
})
// await 要放在 async 函数中.
async function main() {
try {
let result = await p;
//
console.log(result);
} catch (e) {
console.log(e);
}
}
//调用函数
main();
</script>