Promise这样理解更简单

这篇具有很好参考价值的文章主要介绍了Promise这样理解更简单。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Promise小白怎么用?从一个故事开始吧

1、先来一段废话故事

您是一名在古老迷失城市中探险的冒险家。您身处一间装饰华丽的房间中,四周布满了古老的壁画和雕塑。您发现有两个通道分别通向不同的方向,分别是:一个黑暗的通道和一个明亮的通道。

黑暗的通道中充满了神秘的气息,您能感受到其中蕴含的古老力量。您并不知道它会带您去哪里,但您可以感受到其中蕴藏的危险和未知。另一方面,明亮的通道看起来温暖舒适,您可以看到远处照耀的阳光。您能听到一些欢快的音乐声,似乎在那个方向上有一些人在欢庆。

现在,您需要在这两个通道之间做出选择。您会选择哪一个通道呢?您的选择将会影响您接下来的冒险之旅。

2、再来看一段神秘的小短片

https://drive.weixin.qq.com/s?k=AOoAUwfiAAwVgJbsSaAUEA_QbjAFk

3、这么久了还不进入正题

先来了解几个单词,几个Promise的术语

● Promise的三个状态:pending(等待状态)、fulfilled(已成功状态)和 rejected(已失败状态)

● Promise的三个常用回调函数(咱说的是常用):

1. 实例化对象时传入的回调函数

2. then方法的传入的两个回调函数

3. catch方法传入的一个回调函数

以作业为例,继续深入了解Promise

1、开始写作业,此时Promise状态为pending,我们可以理解为初始状态,也可以理解为业务处理中

2、作业完成情况有两种,一种是写完了,一种是被狗吃了

3、无论哪种情况,必须要告诉老师,成功了就通过resolve通道暂存数据,同时会更改状态为成功fulfilled;失败了就通过reject通道暂存数据,同时修改状态为rejected。

4、老师如何获取resolve或reject通道传来的数据呢?可以使用Promise对象的.then方法获取resolve或reject的结果,或者使用.catch方法获取reject通道的信息。

5、简单来一段代码看看

const p = new Promise(function (resolve, reject) {
  resolve('通过成功通道存储数据')
})

//...如果不使用then,提取,则数据一直暂存在p对象中

//提取结果
p.then(function (val) {
  console.log(val)
})

6、这些写法都是固定的,建议使用promise之前一定要充分了解回调函数

7、咱们再升级一下,写作业用了5秒钟

const p1 = new Promise(function (resolve, reject) {
  //写作业用了5秒钟,5秒钟之后,把成功的作业暂存到resolve通道中
  setTimeout(() => {
    resolve('这是作业')
  }, 5000)
})
//上面代码中调用了resolve的时候,then里面的回调函数才会触发,这里有个时间差或者时空差的感觉
p1.then(function (val) {
  console.log(val)
})

8、再升级一下,这作业他也有被狗吃了的时候,我们假定5秒钟之外就被狗吃了,5秒钟之内就是完成的

const p2 = new Promise(function (resolve, reject) {
  //生成一个1~6秒之间的随机数
  const time = Math.random() * 4000 + 2000
  setTimeout(() => {
    if (time <= 5000) {
      resolve('成功交作业啦')
    } else {
      reject(`作业被狗吃了,耗费了${time秒}`)
    }
  }, time)
})
//成功使用then来接,失败了怎么拿到参数呢?
//用then的第二个参数来拿失败的参数
p2.then(function (val) {
  console.log(val)
}, function (err) {
  console.log('估计是被狗吃了', err)
})

9、除了then的第二个参数可以拿到失败的结果,还可以通过catch方法拿到结果,一会再讨论这两种用法的区别,先看catch的用法,注意这里需要连用

p2.then(function (val) {
  console.log(val)
}).catch((reason) => {
  //输出失败原因,大概率是被狗吃了
  console.log('估计是被狗吃了', reason)
})

10、再看一种常用的连用的写法

new Promise(function (resolve, reject) {
  //生成一个1~6秒之间的随机数
  const time = Math.random() * 4000 + 2000
  setTimeout(() => {
    if (time <= 5000) {
      resolve('成功交作业啦')
    } else {
      reject(`作业被狗吃了,耗费了${time}秒`)
    }
  }, time)
}).then(function (val) {
  console.log(val)
}).catch((reason) => {
  //输出失败原因,大概率是被狗吃了
  console.log('估计是被狗吃了', reason)
})

11、一些需注意的地方

        1.  resolve和reject只是一个形参的名字,对应实际的值是promise内部的函数,调用这两个其实调用的就是promise内部的某个函数而已,这个名字可以随便去改,例如

new Promise(function (ok, fail) {
  //此时此刻形参叫ok,但实际代表的是promise内部函数
  ok('ojbk')
}).then((res) => {
  //promise内部会存储数据,传给res这个变量,此时res 值就是ojbk
  console.log(res)
})

        2.  new Promise(构造器的参数是一个函数),这个函数会同步执行,代码执行到这里的时候就会立即执行

12、小结

1.  Promise通过构造函数同步执行,执行结果调用promise的内部函数存储,通常叫resolve和reject,一个是成功时存储存储使用的通道,另一个是失败时存储的通道,无论存储到哪个通道中,都是写代码的人去定义的

2.  then有两个参数,分别是两个函数类型的参数,第一个参数是在调用resolve时会触发,第二个参数是在调用reject时触发

3.  catch方法可以替代then的第二个参数,拿到reject结果

13、附赠then第二个参数和catch的区别

在then的第一个参数里面的代码,如果出现异常的时候,不用手动的try...catch,通过promise实例对象的.catch可以捕获then内出现的异常,但注意,catch不会捕获构造函数代码中的错误,来看例子

new Promise(function (ok, fail) {
  setTimeout(() => {
    //故意5秒后触发k的报错
    console.log(k)
  }, 5000)
}).then((res) => {
  console.log(res)
}).catch(error => {
  //这个时候,error是拿不到那个错误的,他不负责console.log(k)所在代码块中出现的错误
  console.log(error)
})

Promise这样理解更简单

再看一个catch方法能捕获什么地方的错误

Promise这样理解更简单

大概就是这么个大概

二、为什么要这么用,图个啥~

使用 Promise 的主要原因是他可以解决回调地狱(回调嵌套)问题,让代码变得更优雅,逻辑更清晰

举一个生活中的例子,早上起床第一件事是要穿拖鞋,第二件事是洗漱,第三件事是穿衣服,第四件事是查看“身手要钱”,第五件事是打开自家房门出去开车上班,每件事都需要串行,每一步与下一步都有关联关系

function foo() {
  //1、穿拖鞋开始
  setTimeout(() => {
    //1、2秒后穿拖鞋完成
    //2、洗漱开始
    setTimeout(() => {
      //2、2秒后洗漱完成
      //3、穿衣服开始
      setTimeout(()=>{
        //3、穿衣服完成
        //....不好意思看官,后边还有好几个步骤咱就意思一下,再写就吐了
      },2000)
    }, 2000)
  }, 2000)
}
foo()

就写这几层吧,是不是太恶心了,下面我们使用Promise来改造一下

new Promise((resolve, reject) => {
  //1、穿拖鞋
  setTimeout(() => {
    resolve('穿拖鞋搞定')
  }, 2000)
}).then(val => {
  //等待穿拖鞋完成后,会调用这个函数
  //2、洗漱
  //注意此处!!!,必须使用return 返回一个新的promise来完成链式调用
  const p = new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('洗漱搞定')
    }, 2000)
  })
  return p
}).then(val => {
  //3、穿衣服,此处直接返回,没有使用中间变量
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('穿衣服搞定')
    }, 2000)
  })
}).then(val => {
  //4、查看“身手要钱”
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('查看“身手要钱”搞定')
    }, 2000)
  })
}).then(val => {
  //5、开车去上班
  // 元气满满的一天
  console.log(val+'元气满满的一天')
})

就图这~

Promise这样理解更简单

三、Promise其他方法

那么多方法,不讲那么多,race、all什么的网上一抓一大把

说说语法糖await和async的用法

先了解一个基础规则

● await必须修饰的是Promise对象

● await必须在async中使用

● await只能接收resolve通道的结果,reject结果会导致报错

● await修饰的代码在执行时,代码是卡住的,类似于alert,这句代码不执行完,后边的代码不会向下执行,这也类似于线程同步执行的概念,这也是await有用之处

● async修饰的必须是函数

● async修饰后的函数在执行之后会转为Promise对象

看一段简单的代码

async function foo() {
  let k = await new Promise(function (resolve, reject) {
    setTimeout(() => {
      resolve('qfedu')
    }, 2000)
  })
  console.log(k)
}

foo()

这样用倒是更麻烦,我们把要处理的事黏黏糊糊多弄一些试一试

async function foo() {
  let level1 = await new Promise((resolve, reject) => {
    //1、穿拖鞋
    setTimeout(() => {
      resolve('穿拖鞋搞定')
    }, 1000)
  })
  //拿着第一步的结果,去第二步进行操作

  let level2 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level1 + '洗漱搞定')
    }, 1000)
  })

  let level3 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level2 + '穿衣服搞定')
    }, 1000)
  })

  let level4 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level3 + '查看“身手要钱”搞定')
    }, 1000)
  })

  console.log(level4 + ',之后开车去上班,元气满满的一天')
}

foo()

输出结果:

Promise这样理解更简单

这样代码看起来更加简洁,当然要重点考虑的问题是在整个从上到下的调用过程中,任何一个环节出现问题,都会影响下面的代码

再来,我们把代码聚焦到foo()方法调用之前和调用之后

console.log(1)
foo()  //这个会输出 穿拖鞋搞定洗漱搞定穿衣服搞定查看“身手要钱”搞定......等
console.log(2)

思考一下,程序输出的顺序

注意,使用async包裹的代码,属于异步代码,会在同步代码之后执行

Promise这样理解更简单

我们给按钮添加一个点击事件,看点击按钮如何让程序使用await顺序执行

async function foo() {
  let level1 = await new Promise((resolve, reject) => {
    //1、穿拖鞋
    setTimeout(() => {
      resolve('穿拖鞋搞定')
    }, 1000)
  })
  //拿着第一步的结果,去第二步进行操作

  let level2 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level1 + '洗漱搞定')
    }, 1000)
  })

  let level3 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level2 + '穿衣服搞定')
    }, 1000)
  })

  let level4 = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(level3 + '查看“身手要钱”搞定')
    }, 1000)
  })

  console.log(level4 + ',之后开车去qfedu上班,元气满满的一天')
}

window.onclick = foo;
//或者是
window.onclick = async function(){
  //todo ...
  //await new Promise...
  //await new Promise...
  //await new Promise...
  //...
}

实际场景中,await 与async通常用来处理ajax请求类代码,让代码更简洁,再次强调,await只接收resolve结果,注意reject和error的错误要使用try...catch...处理异常文章来源地址https://www.toymoban.com/news/detail-411517.html

到了这里,关于Promise这样理解更简单的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 视频中的声音怎么提取出来?这样做提取出来很简单

    提取视频中的声音可以有多种用途。例如,我们可能希望从视频中提取音乐或音效,以在其他项目中使用。或者,可能需要将视频中的对话转录为文本,以便更轻松地编辑和共享内容。无论目的是什么,提取视频中的声音都可以帮助我们更好地利用视频资源。那么怎么提取呢

    2024年02月11日
    浏览(41)
  • ES6基础知识六:你是怎么理解ES6中 Promise的?使用场景?

    一、介绍 Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大 在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码 阅读上面代码,是不是很难受,上述形成了经典的回调地狱 现在通过Promise的改写上面的

    2024年02月15日
    浏览(49)
  • 投影仪怎么看电视节目?超简单几个步骤小白也能马上学会

    小时候我们大院看电视节目都是通过胶卷投影实现的,简单原理就是把图像或者视频投射到大白布上,让更多的人一起来欣赏,这是最开始的投影概念。由于现在科学技术的进步,不同于以前的投影设备,更加智能化的投影仪应运而生了,机器里边会带有安卓的操作系统与视

    2024年02月11日
    浏览(46)
  • 灾备是什么意思?怎么简单理解?

    最近看到不少小伙伴在问,灾备是什么意思?有什么用?如何简单理解?这里就听我们小编简单说说吧! 灾备是什么意思? 灾备指的是用现有的科学技术手段和方法,提前建立起可靠的应急方式,来应对突发事件的发生。其包括容灾系统和备份系统。 灾备有什么用? 1、保

    2024年02月11日
    浏览(39)
  • 小白咋写第一篇Blog,建议像这样

    比如说,我最开始一直在研究鲲鹏处理器,是一个偏底层的架构方面的内容。 我学完了C语言,python、单片机、嵌入式的一些基础知识之后,真的对这类问题充满兴趣,发现 一个野生小白(本人) 相较于其他的方面更适合于 爬一爬相关的内容(文档、博客) ,系统的开始看了

    2024年02月08日
    浏览(40)
  • 作为代码小白,我是这样成为自动化大神的!

    robot是一款自动化测试的工具,能够实现接口自动化测试、UI自动化测试。 它的主要特色就是: 由 驱动来完成测试用例 测试用例格式可以为txt/html等, 非代码的形式,支持中文哦 。 由python实现,开源。 这里有2个重要的概念需要大家先掌握一下: 简单来说:

    2024年02月10日
    浏览(39)
  • 【Python基础知识】在VSCode中怎么配置Python开发环境?真的超简单!小白也能掌握

    前言:VS Code 里是不包括 Python 的,所以你首先得安装一个 Python。 安装完 python 之后,我们可以用任何一个文本编辑工具开始写 python 代码,然后在 cmd 中运行代码。 在 VS Code 中,在不安装任何插件的情况下,也可以运行 python 代码。 新建一个 test.py 文件,输入 print(\\\'Hello Wor

    2024年02月03日
    浏览(53)
  • 前端Promise理解

    阐述promsie的基本概念 介绍实例方法then、catch、finally 介绍静态方法all、allSettled、race、any、resolve、reject 执行器 executor ◐ 当通过new创建Promise对象时,需要传入一个回调函数,称之为 executor ◐ executor 会在new promise时 会被立即执行 ,并且可传入另外两个回调函数 resolve 、 rej

    2024年02月19日
    浏览(88)
  • 深入理解 JavaScript Promise

    JavaScript中的Promise是一种处理异步操作的机制,它提供了一种优雅的方式来处理回调函数地狱和异步代码的流程控制。本文将深入介绍JavaScript中的Promise,帮助读者更好地理解和应用Promise。 Promise是一个代表异步操作的对象,它可以有三种状态:pending(进行中)、fulfilled(已

    2024年02月09日
    浏览(68)
  • 【异步系列三】10道 Promise 面试题彻底理解 Promise 异步执行顺序

    上一篇文章详细说明了关于 Promise 的概念以及执行顺序,Promise 作为 JavaScript 中的关键特性,无论是在日常工作中还是面试中,我们都必须掌握它。 前段时间在网上看到了一些关于 Promise 的面试题,质量很好,在这里整理到下面,并加上我一些自己的见解,欢迎斧正! 1. 同步

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包