首页 > 编程语言 >Javascript(笔记53) - promise - 3 几个关键问题

Javascript(笔记53) - promise - 3 几个关键问题

时间:2022-11-26 23:04:37浏览次数:56  
标签:resolve console log Javascript value Promise 53 reject promise

如何改变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);

Javascript(笔记53) - promise - 3 几个关键问题_链式调用


2)reject(reason)

let p = new Promise((resolve,reject)=>{
// 2. reject 函数, pending => reject
reject("Error");
});
console.log(p);

Javascript(笔记53) - promise - 3 几个关键问题_javascript_02


3)抛出异常

let p = new Promise((resolve, reject) => {
// 3. 抛出异常, pending => reject
throw "Err";
});
console.log(p);

Javascript(笔记53) - promise - 3 几个关键问题_promise_03


一个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);

Javascript(笔记53) - promise - 3 几个关键问题_promise_04

reuslt 的结果状态有什么样的特点,由谁来决定的?

第一种,抛出异常:result 的状态变失败;

let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
throw "Err";
});
console.log(result);

Javascript(笔记53) - promise - 3 几个关键问题_链式调用_05

第二种,返回结果是 非promise 类型的对象,如 数值、字符串等:result 状态变成功;

let p = new Promise((resolve, reject) => {
resolve('ok');
});
let result = p.then(value => {
return 521;
});
console.log(result);

Javascript(笔记53) - promise - 3 几个关键问题_链式调用_06

这种情况,即使只写 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);

Javascript(笔记53) - promise - 3 几个关键问题_promise_07

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);

Javascript(笔记53) - promise - 3 几个关键问题_链式调用_08


如果一开始 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 也不会输出了。 


标签:resolve,console,log,Javascript,value,Promise,53,reject,promise
From: https://blog.51cto.com/ahuiok/5889233

相关文章

  • javascript 执行上下文
    <script>//执行上下文,顺序执行到此出会产生一个全局的执行上下文(ECG),并把全局ECG放到ECS(执行上下文栈)中//VO:GO(globanobject)对浏览器而言,window即......
  • setcontext+53、61的利用
    ‍ubuntu18限制数量0x10、UAF、禁exe​add(0x420)add(0x420)dele(0)add(0x90)show(1)r.recvuntil("Content:")base=u64(r.recv(6)+b'\x00'*2)-0x3ec090print......
  • 『题解』UVA 10534 Wavio Sequence
    题目传送门题意\(Wavio\)是整数序列,有如下特点:它的长度总为奇数,即\(2n+1\);前\(n+1\)个数构成一个严格的上升序列,后\(n+1\)个数构成一个严格下降的序列;任意......
  • dojo利用promise实现多个异步校验
    代码如下://敏感词过滤varpromiseAll=checkSenstiveWords();promiseAll.then(function(results){ //console.log("results=>",results) //console.log("v1=>"......
  • 手把手教你使用ts 一步一步的去完成一个Promise
    前奏笔者公司前端小组,线上出现了因为Promise用错了而导致的问题。本文的出发点不仅是了解Promise,主要目的是跟着特性去写一个Promise。所以前提是你已经掌握了Promise的......
  • npm 打包报错JavaScript heap out of memory(亲测可行)
    解决办法:1.修改package.json加–max_old_space_size=81922.安装并执行increase-memory-limit//全局安装cnpminstall-gincrease-memory-limit//项目内运行increase-memory......
  • TypeScript/Javascript 泛型字典
    typescript是javaScript的超集,相当于把弱类型的js变成了强类型的语言,并且实现了封装(成员私有),更方便面向对象编程。然鹅,typescript并没有扩增原生JS的内容,比如:支持了import......
  • javascript面试题
    1.null和undefined区别首先Undefined和Null都是基本数据类型,这两个基本数据类型分别都只有一个值,就是undefined和null。undefined代表的含义是未定义,null代表......
  • 如何用JavaScripte和HTML 实现一整套的考试答题卡和成绩表
    相信在学校的你都有这样的体验,临近考试,要疯狂的“背诵”否则成绩单就要挂零,因为答题卡全部涂抹都是错的。那么毕业多年的你,没有了考试,有没有一丝怀念涂答题卡的时候,有没有......
  • 力扣153(java&python)-寻找旋转排序数组中的最小值(中等)
    题目:已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums=[0,1,2,4,5,6,7]在变化后可能得到:若旋转4次,则可以得到[4,5,6,......