温习Promise基础可以看看这篇文章:Promise从入门到精通,小白必看
Promise 的几个关键问题
1.改变 promise状态的三种方式
<script>
let p = new Promise((resolve, reject) => {
//1. resolve 函数状态会由pending变为resolved
// resolve('ok'); //Promise {<fulfilled>: "ok"}
//2. reject 函数
// reject("error");//Promise {<rejected>: "error"}
//3. 抛出错误
throw '出问题了';//Promise {<rejected>: "出问题了"}
});
console.log(p);
</script>
2.一个 promise 指定多个成功/失败回调函数,都会调用吗?
当 promise 改变为对应状态时都会调用。
<script>
let p = new Promise((resolve, reject) => {
resolve('OK');//状态改变(e.g.:pending变成resolved)才会执行回调p.then
});
p.then(value => {///指定回调 - 1
console.log(value);
});
p.then(value => {//指定回调 - 2
alert(value);
});
</script>
3.改变promise状态和指定回调函数谁先谁后?
都有可能,常规是先指定回调再改变状态,但也可以先改状态再指定回调. 如何先改状态再指定回调? (1)在执行器中直接调用 resolve()/reject() (2)延迟更长时间才调用 then() 什么时候才能得到数据? ①如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据 ②如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000); // 有异步就先指定回调,否则先改变状态
});
p.then(value => {//回调
console.log(value);
})
4.promise.then()返回的新promise的结果状态由什么决定?
由then()指定的回调函数执行的结果决定。
<script>
let p = new Promise((resolve, reject) => {
resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
//console.log(value);
//1. 抛出错误,新promise变为rejected, reason为抛出的异常
//throw '出了问题';
//2. 返回结果是非 Promise 类型的对象,新promise变为resolved, value为返回的值
// return 521;
//3. 返回的是另一个新promise, 此promise的结果就会成为新promise的结果
return new Promise((resolve, reject) => {
// resolve('success');
reject('error');
// });
}, reason => {
console.warn(reason);
});
console.log(result);
</script>
5.promise如何串连多个操作任务?
promise 的 then() 返回一个新的 promise,可以并成 then() 的链式调用,通过 then 的链式调用串联多个同步/异步任务。
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
return new Promise((resolve, reject) => {
resolve("success");
});
}).then(value => {
console.log(value); // success,最上边状态改变,第一个p.then回调才会执行,返回成功的promise,这里的then才会执行
}).then(value => {
console.log(value); // undefined
})
6.promise异常穿透
当使用promise的then链式调用时, 可以在最后指定失败的回调, 前面任何操作出了异常, 都会传到最后失败的回调中处理。
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
// reject('Err');
}, 1000);
});
p.then(value => {
// console.log(111);
throw '失败啦!';
}//,reason => {throw reason} 等价于reason => Promise.reject(reason),异常穿透使得可以省略每个then后的reason。
).then(value => {
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
</script>
7.中断promise链的唯一方法
当使用 promise 的 then 链式调用时想在中间中断,不再调用后面的回调函数 办法:在回调函数中返回一个 pending 状态的 promise 对象。
<script>
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK');
}, 1000);
});
p.then(value => {
console.log(111);
//有且只有一个方式
return new Promise(() => {});
}).then(value => {//回调函数then得在上面状态改变之后才能执行,由于上面状态是pending所以在这就卡住了
console.log(222);
}).then(value => {
console.log(333);
}).catch(reason => {
console.warn(reason);
});
</script>