一、如何修改promise对象状态
修改promise对象状态有三种方法:
(penging未改变时状态,fulfilled (resolved)成功状态,rejected失败状态)
- resolve 函数
resolve(‘ok’); // pending => fulfilled (resolved) - reject 函数
reject(“error”);// pending => rejected - 抛出错误
throw ‘出问题了’;//pending => rejected
注意:
一个promise对象可以由pending状态可以转变为fulfilled (resolved)或rejected状态,但不能由fulfilled (resolved)或rejected状态转变为pending状态,也不能在fulfilled (resolved)或rejected状态中相互转变。简而言之,一个promise对象只能由pending状态转变一次状态!
二、能否执行多个回调
同一个promise对象是可以同时执行多个回调的,不管是fulfilled (resolved)或rejected状态。
三、改变状态与指定回调顺序问题
改变 promise 状态和指定回调函数谁先谁后?
-
都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调。
-
如何先改状态再指定回调?
① 在执行器中直接调用 resolve()/reject()
② 延迟更长时间才调用 then() -
什么时候才能得到数据?
① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据。
② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据。
四、then方法的返回结果由什么决定
- 简单表达: 由 then()指定的回调函数执行的结果决定。
- 详细表达:
① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常。
② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值。
③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果。
举例:
<script>
let p = new Promise((resolve, reject) => {
resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
// console.log(value);
//1. 抛出错误
//throw '出了问题';
//2. 返回结果是非 Promise 类型的对象
// return 521;
//3. 返回结果是 Promise 对象
return new Promise((resolve, reject) => {
// resolve('success');
reject('error');
});
}, reason => {
console.warn(reason);
});
console.log(result);
</script>
五、promise如何串联多个任务
- promise 的 then()返回一个新的 promise, 可以看成 then()的链式调用
- 通过 then 的链式调用串连多个同步/异步任务
<body>
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
return new Promise((resolve, reject) => {
resolve("success");
});
}).then(value => { //success
console.log(value);
}).then(value => { //undefined
console.log(value);
})
</script>
</body>
六、异常穿透现象是怎么回事
- 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调。
- 前面任何操作出了异常, 都会传到最后失败的回调中处理。
<body>
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
// reject('Err');
}, 1000);
});
p.then(value => {
// console.log(111);
throw '失败啦!';
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
</script>
</body>
一般情况下会按照顺序运行then函数输出,但如果遇到throw抛出问题,就会直接跳到catch中,忽略其它then函数链。
七、如何中断Promise链条
当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数。
方法: 在回调函数中返回一个 pendding 状态的 promise 对象。
<body>
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
console.log(111);
//有且只有一个方式
return new Promise(() => {});
}).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
</script>
</body>
以上代码资料来源:尚硅谷Web前端Promise教程从入门到精通