真正搞懂promise 与同步异步 新增面试话术

老大难的promise,属于道理我都懂,也会用,但就是总感觉没理解透彻
随手B站刷到一个视频 解决了我多年疑惑

B站链接

同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

模拟一

function one (){
     return 'I am one';
}
function two () {
     setTimeout(()=>{
           return 'I am two';
     },3000);
     
}
function three () {
     return 'I am three';
}

console.log(one())
console.log(two())
console.log(three())

在这里插入图片描述

  • 后台数据请求都是异步,而JS是单线程。这里用定时函数模拟请求,会发现等不到请求完成就会先执行输出,导致输出undefined

模拟二


function one (){
     return 'I am one';
}
function two () {
     return new Promise((resolve,reject)=>{
          setTimeout(()=>{
                resolve ('I am two');
          },3000);
     })
}
function three () {
     return 'I am three';
}

console.log(one())
console.log(two())
console.log(three())

在这里插入图片描述
这里因为还是单线程直接执行,没有等到promise成功态就输出了promise对象,此时的promise对象处于pending状态。

模拟三


function one (){
     return 'I am one';
}
function two () {
     return new Promise((resolve,reject)=>{
          setTimeout(()=>{
                resolve ('I am two');
          },3000);
     })
}
function three () {
     return 'I am three';
}

console.log(one())
console.log(await two())
console.log(three())

在这里插入图片描述
配合await,代码执行时await有返回结果后才会继续向下执行。
这里会先输出 I am one 然后等待三秒再输出 I am two I am three

  • 最初的解决方式是使用回调函数的方法,将后续操作一并传入,这样就可以实现拿到数据后再执行其他逻辑。
  • 但是回调过多会导致回调地狱,难以维护。promise的主要贡献就是解决了回调地狱,让请求代码更简洁。再补充async后写起来就更加舒服了。

一个值得注意的点

想起来之前面试 有一个面试官问我用promise为什么还要手写promise对象 await返回的就是promise对象,当时一下没想明白。现在回想起来…还好没去那家公司
MDN中对await的描述

如果该值不是一个 Promise,await 会把该值转换为已正常处理的Promise,然后等待其处理结果。

async function f2() {
  var y = await 20;
  console.log(y); 
}f2();
//输出20

await返回的就是promise对象,这句话其实没错,但我们结合实际开发看看
用定时器模拟异步请求,场景是需要拿到接口返回结果再进行下一步操作。

async function f2() {
  var y = await two();
  console.log(y); // 20
  console.log('下一步')
}
function two () {
     setTimeout(()=>{
           return 'I am two';
     },3000);
}
f2()
//输出 undefined
//     下一步 

这样返回的结果是undefined,异步请求若不进行手动封装,靠await自动处理,await的阻断效果是不会出现的,数据依然拿不到。
正确写法是:

async function f2() {
  var y = await two();
  console.log(y); // 20
  console.log('下一步')
}
function two () {
    return new Promise(resolve=>{
         setTimeout(()=>{
               resolve( 'I am two')
         },3000);
    })
}
f2()
//等待三秒后
//输出 I am two
//     下一步 

面试话术:

JS是单线程,但后台请求是异步执行的。开发中常常会遇到需要拿到接口数据后执行必要逻辑。
当然,这里可以使用回调函数,但代码量大了会难以维护形成回调地狱。
而使用promise函数配合async await就可以完美解决这类问题
某一步操作设置await等待返回的promise对象,promise中进行异步请求,拿到数据后在改为成功态,即可进行后续操作。
用同步的方法写异步,维护性高。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跳动的世界线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值