如何改变Promise的状态?
1) resolve(value):如果当前是 pending 就会变为 resolved(或 fulfilled);
2) reject(reason):如果当前是 pending 就会变为 rejected;
3) 抛出异常:如果当前是 pending 就会变为 rejected;
1)resovle(value)
let p = new Promise((resolve,reject)=>{
// 1. resolve 函数, pending => fulfilled(resolved)
resolve("Success");
});
console.log(p);
2)reject(reason)
let p = new Promise((resolve,reject)=>{
// 2. reject 函数, pending => reject
reject("Error");
});
console.log(p);
3)抛出异常
let p = new Promise((resolve, reject) => {
// 3. 抛出异常, pending => reject
throw "Err";
});
console.log(p);
一个Promise指定多个“成功或失败”的回调函数,都会调用么?
当 Promise 改变为对应状态时都会调用 ;
指定多个 then() 方法,是否都会调用? 要看 Promise 对象的状态是否改变,改变了就调用,不改变就不会调用;
let p = new Promise((resolve, reject) => {
// 调用 resolve ,使 p 的状态改变为成功
resolve('ok');
});
// 指定回调 1
p.then(value=>{
console.log(value); // ok
});
// 指定回 2
p.then(value=>{
console.log(value); // ok
});
函数体里调用 resolve() ,把 p 对象的状态改为成功;后面2个 then() 方法的回调都会调用,并输出;
如果函数体里不调用 resolve() ,把他注释了,后面的回调也就不会输出了;
let p = new Promise((resolve, reject) => {
// resolve('ok'); // 注释函数
});
p.then(value=>{
console.log(value); //
});
p.then(value=>{
console.log(value); //
});
改变 Promise 状态和指定回调函数谁先谁后?
改变状态可以使用 resolve 和 reject 等,前面已经说过,下面示例使用 resolve;
指定回调函数可以使用 then 和 catch 等方法,下面示例使用 then ;
那这个问题可以简化为:改变状态的 resolve 先执行,还是指定回调的 then 先执行?
1)都有可有,一般先指定回调再改变状态,但也可以先改状态再指定回调;
改变状态先执行的情况:当执行器函数(excutor)中的任务是同步任务时,调用 resolve ,那就是先改变状态再执行回调;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
p.then(value => {
console.log(value); // ok
});
指定回调先执行的情况:当执行器函数中是异步任务时,也就是说改变状态需要一段时间,这种情况下 then 方法先执行,改变状态后执行;
实际开发中,执行器函数中是异步任务的情况居多;
let p = new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('ok');
},3000);
});
p.then(value => {
console.log(value);
});
其实,先改变状态还是先指定回调,我怎么感觉意义并不大,因为都是确定的,谁先谁后不一样么?
2)如何先改状态再指定回调 ?
1、 在执行器中直接调用 resolve() / reject();
2、 延迟更长时间才调用 then();
3)什么时候才能得到数据?(回调函数什么时候执行)
1、 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据;
2、 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据;
Promise.then() 返回的新 promise 的结果状态由什么决定?
1) 简单表达:由 then() 指定的回调函数执行的结果决定;
2) 详细表达:
1、如果抛出异常,新 promise 变为 rejected,reason 为抛出的异常;
2、如果返回的是 非promise 的任意值,新 promise 变为 resolved ,value 为返回的值;
3、如果返回的是另一个新promise,此 promise 的结果就会成为新promies 的结果;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => { // 把then方法的结果赋给 result
console.log(value);
});
console.log(result);
reuslt 的结果状态有什么样的特点,由谁来决定的?
第一种,抛出异常:result 的状态变失败;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
throw "Err";
});
console.log(result);
第二种,返回结果是 非promise 类型的对象,如 数值、字符串等:result 状态变成功;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
return 521;
});
console.log(result);
这种情况,即使只写 return; 啥也不返回(那就是返回 undefined),也是成功状态;
第三种,如果返回的结果是promise 对象,那 return 的 promise 的状态决定 result 的状态;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
return new Promise((resolve,reject)=>{
resolve("Success");
});
});
console.log(result);
return 的 Promise 状态是成功,那么 result 的状态就是成功 ;
反之,return 的 Promise 状态是失败,那么 result 的状态就是失败 ;
let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
return new Promise((resolve,reject)=>{
reject("Error");
});
});
console.log(result);
如果一开始 p 返回是 reject() 呢?其实是一样的;那判断 result 状态将发生在 reason 的回调中,规则跟上面一样;
let p = new Promise((resolve, reject) => {
reject('Err');
});
let result = p.then(value => {
console.log(value);
},reason=>{
throw "Err"; // 抛出异常,返回 失败;
// return "Ok"; // 返回字符串(非Promise)值,返回 成功;
// return new Promise((resolve,reject)=>{}); // 看 Promise 执行器中的返回状态来决定
});
console.log(result);
Promise 如何串连多个操作任务?
1)Promise 的 then() 返回一个新的 promise ,可以开启 then() 的链式调用;
2)通过 then() 的链式调用,串连多个 同步/异步任务;
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Ok');
}, 2000);
});
p.then(value=>{
return new Promise((resolve,reject)=>{
resolve("Success");
});
}).then(value=>{
console.log(value); // Success 等待2S后输出;
}).then(value=>{
console.log(value); // undefined
});
p 对象的执行器返回 resolve(),那么第一个 then 将执行 value 的回调,也返回一个 resolve();
那第二个 then 也将执行 value 的回调,输出返回的值,即:Success;但是没有返回什么值,即非promise ,接上面的规则得知,即使什么也没返回,那状态就是成功;
所以第三个 then 将执行 value 的回调,输出值为 undefined;
Promise异常穿透
1)当使用 Promise 的 then 链式调用时,可以在最后指定失败的回调;
2)前面任何操作出了异常,都会传到最后失败的回调中处理;
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Ok');
}, 1000);
});
p.then(value=>{
console.log(111); // 111
}).then(value=>{
console.log(222); // 222
}).then(value=>{
console.log(333); // 333
}).catch(reason=>{
console.warn(reason);
});
就是把处理失败回调的 catch 放在最后,前面任何操作出异常,都会传到这个回调中来处理;
上面是个正常的一路成功的回调,并没有用到 catch 回调 ,改下代码,让它能执行这个回调 ;
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('Ok');
reject("Err"); // 在源头上改变为失败;
}, 1000);
});
p.then(value=>{
console.log(111);
}).then(value=>{
console.log(222);
}).then(value=>{
console.log(333);
}).catch(reason=>{
console.warn(reason); // Err, 直接跳到最后,只输出Err
});
再改一下,改到其中一个 then 方法上:
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Ok');
}, 1000);
});
p.then(value=>{
console.log(111); // 111
throw "Err";
}).then(value=>{
console.log(222);
}).then(value=>{
console.log(333);
}).catch(reason=>{
console.warn(reason); // Err , 也会跳到最后, 执行失败;
});
异常穿透,比较好理解;
中断 Promise链
1) 当使用 promise 的then链式调用时,在中间中断,不再调用后面的回调函数;
2)办法:在回调函数中返回一个 pending 状态的 promise 对象;
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Ok');
}, 1000);
});
p.then(value=>{
console.log(111); // 111
}).then(value=>{
console.log(222); // 222
}).then(value=>{
console.log(333); // 333
});
这是个可以一直 then 下去的链式调用,要中断 then,可以在其中一个 then 上返回状态为 pending 的 promise 对象;
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Ok');
}, 1000);
});
p.then(value=>{
console.log(111);
return new Promise(()=>{}); // 加个没有状态返回的 promise 就会中断 then 的链式调用
}).then(value=>{
console.log(222);
}).then(value=>{
console.log(333);
});
因为没有状态传递,所以 then 中断了。后面的 222, 333 也不会输出了。