我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript中Promise的原理是什么及如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript中Promise的原理是什么及如何使用

这篇文章主要介绍了JavaScript中Promise的原理是什么及如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中Promise的原理是什么及如何使用文章都会有所收获,下面我们一起来看看吧。

按照我往常的理解,Promise是一个构造函数,有all、resolve、reject、then、catch等几个方法,一般情况下,在涉及到异步操作时才会用到Promise。

所以我接下来先new一个Promise对象,并在其中进行一些异步操作:

// 使用Promise的时候一般会把它包裹在一个函数中,并在函数的最后返回这个Promise对象function runPro()(    var a = new Promise((resolve, reject) => {        setTimeout(() => {            console.log('work done!');            resolve('success');        }, 1000);    });    return a;)runPro()

在上面的代码中,Promise的构造函数接收一个箭头函数作为参数,这个箭头函数又有两个参数,分别是resolve和reject,我在这个箭头函数中使用setTimeout进行了一些异步操作,异步操作中执行了resolve方法,并给resolve方法传了一个字符串‘success’作为参数。

执行这段代码会发现,等待了1秒钟后(因为我在setTimeout中设置的等待时间是1000毫秒),输出了‘work done!’。

这时候并没有发现Promise有什么特别的作用,而且resolve和reject这两个的作用也并没有体现出来。

之前我们说过Promise这个构造函数上有then、catch方法,在上面的代码片段中,runPro函数最后return了一个Promise对象,所以我们可以在runPro函数执行完成之后使用then对Promise对象进行进一步的操作:

runPro().then((res) => {    console.log('then:', res);    //TODO something});

输出结果:

JavaScript中Promise的原理是什么及如何使用

在runPro返回的Promise对象上直接调用then方法,then方法接收一个函数作为参数A,并且这个箭头函数也会接收一个参数B,这个参数B的值就是前面代码中resolve方法所传递的字符串‘success’。

执行代码,会在1秒后首先输出‘work done!’,紧接着输出‘then: success’。

这个时候,就可以简单的体现出来Promise的作用了,在前面的代码中,then方法就像是Promise的回调函数,当Promise中的异步操作执行完之后,通过链式调用的方式执行回调函数。

这里的关键点就在于链式调用上,当实际使用中遇见多层回调的情况时,Promise的强大之处才能够体现出来:

function runPro2(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro2');}, 1000);});return a;};function runPro3(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro3');}, 1000);});return a;};runPro().then(() => {return runPro2();}).then(() => {return runPro3();}).then(() => {console.log('all done')})

到这里为止,大概已经明白了,Promise是一个在异步操作过程中,等待其中异步操作完成之后执行其回调函数的一种结构体。但是其中的原理还是模糊不清,其中resolve和reject这两个参数还没有搞清楚,只知道在前面的几个代码片段中都调用了resolve函数,resolve是做什么的并没有体现出来。

关于resolve和reject,我以前的理解是Promise中的异步操作执行成功后调用resolve函数,异步操作执行失败后调用reject函数,后来发现这种理解其实是不准确的。

在理解这两个函数的正确作用之前,我们首先要知道Promise一个重要的特性:状态

Promise的状态:

一个Promise对象的当前状态必须为以下三种状态中的一种:等待(Pending)、完成(Fulfilled)、拒绝(Rejected)。

Pending:

异步操作完成之前,Promise处于等待状态,这时候的Promise可以迁移至Fulfilled或者Rejected。

Fulfilled:

异步操作完成之后,Promise可能从Pending状态迁移至Fulfilled状态,Fulfilled状态的Promise必须拥有一个不可变的终值,并且Fulfilled状态的Promise不能迁移为其他状态。

Rejected:

异步操作完成之后,Promise可能从Pending状态迁移至Rejected状态,Rejected状态的Promise必须拥有一个不可变的拒绝原因,并且Rejected状态的Promise不能迁移为其他状态。

了解了Promise的三种状态之后,我们再来说说resolve和reject这两个函数的作用:

  • resolve函数将Promise设置为Fulfilled状态,reject函数将Promise设置为Rejected状态。

  • 设置为Fulfilled或者rejected状态后,即表示Promise中的异步操作执行完成,这时程序就会执行then回调函数。

  • resolve和reject函数传递的参数,将由then函数中的箭头函数接收。

实际上,理解Promise的关键点就在于这个状态,通过维护状态、传递状态的方法来进行及时的回调。

所以,如下面代码所示,当使用Promise进行异步操作的时候,其中有几个关键点需要特别注意:

在一个函数中new了一个Promise对象之后,函数的最后必须把这个Promise对象return出来,否则这个函数就无法使用then函数进行回调;

异步操作中必须执行resolve或者reject函数,否则这个Promise一直处于Pending状态,代码就不会执行它的回调函数。

function runPro(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('resolve');console.log('this is runPro');}, 1000);});return a;}runPro().then((res) => {console.log(res);})

同样的道理,当异步操作执行失败时,代码通过执行reject函数的方式,将Promise的状态设置为Rejected,并返回一个拒绝原因:

function runPro(item){var a = new Promise((resolve, reject) => {setTimeout(() => {if(item >= 18) {console.log('item 大于 18');resolve('一切正常!');}else {console.log('item 小于 18');reject('18+电影不允许放映!');}}, 1000);});return a;}runPro(13).then((res) => {console.log('resolve:',res);},(rej) => {console.log('reject:', rej);})

我们给runPro函数传递不同的参数,runPro接受参数后进行一个异步的判断,如果这个参数的值小于18,执行reject函数,反之则执行resolve函数,异步操作完成之后,执行then回调函数,这里的回调函数可以接收两个箭头函数作为参数,分别对应了resolve函数的回调和reject函数的回调,这两个箭头函数可以分别拿到resolve和reject传递的参数。

如下面截图所示,分别给runPro传递两个不同值后,得到了两种不同的结果:

JavaScript中Promise的原理是什么及如何使用

catch函数的用法

在Promise中,catch函数可以替代reject函数使用,用来指定接收reject的回调:

function runPro(item){var a = new Promise((resolve, reject) => {setTimeout(() => {if(item >= 18) {console.log('item 大于 18');resolve('一切正常!');}else {console.log('item 小于 18');reject('18+电影不允许放映!');}}, 1000);});return a;}runPro(13).then((res) => {console.log('resolve:',res);}).catch((rej) => {console.log('catch:', rej);})

如上面代码所示,对调函数then只有一个箭头函数作为参数,这种情况下,这个箭头函数就被指定用来接收resolve函数的回调,而reject函数的回调则被catch函数来接收:

JavaScript中Promise的原理是什么及如何使用

这个地方使用catch函数来接收reject的回调有一个优点,当前面的then回调函数中出现位置错误时,catch函数可以对错误信息进行处理,而不会导致代码报错。这个原理和常用的try/catch语句相同。

function runPro(item){    var a = new Promise((resolve, reject) => {        setTimeout(() => {            if(item >= 18) {                console.log('item 大于 18');                resolve('一切正常!');            }else {                console.log('item 小于 18');                reject('18+电影不允许放映!');            }        }, 1000);    });    return a;}runPro(19).then((res) => {    console.log(adc); // 这里的adc是一个未定义的变量,当代码执行到这里时,会抛出Error信息导致代码卡死    console.log('resolve:',res);}, (rej) => {    console.log('reject:',rej);});runPro(19).then((res) => {    console.log(abc); // 这里的abc是一个未定义的变量,但是由于后边使用.catch函数进行了异常捕获,所以程序不会报错。而且错误原因也会作为参数传递到后面.catch函数的参数中    console.log('resolve:',res);}).catch((rej) => {    console.log('catch:', rej);})

JavaScript中Promise的原理是什么及如何使用

all函数 / race函数并行异步操作

Promise的all函数和race函数都提供了并行异步操作的能力,二者的区别在于,当这些并行的异步操作耗时不同时,all函数是在所有的异步操作都执行完之后才会执行,而race函数则会在第一个异步操作完成之后立即执行。

function runPro1(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro1');}, 1000);});return a;}function runPro2(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro2');}, 2000);});return a;};function runPro3(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro3');}, 3000);});return a;};Promise.all([runPro1(), runPro2(), runPro3()]).then((res) => {console.log('all:', res);})

JavaScript中Promise的原理是什么及如何使用

function runPro1(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro1');}, 1000);});return a;}function runPro2(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro2');}, 2000);});return a;};function runPro3(){var a = new Promise((resolve, reject) => {setTimeout(() => {resolve('success');console.log('this is runPro3');}, 3000);});return a;};Promise.races([runPro1(), runPro2(), runPro3()]).then((res) => {console.log('all:', res);})

JavaScript中Promise的原理是什么及如何使用

如上两个代码片段所示,all函数和race都接收一个数组作为参数,这个数组中的值就是我们要进行并行执行的异步操作。这里我们同样使用then函数作为异步操作完成的回调函数。同时我们通过console输出发现,在race函数的回调函数开始执行的时候,另外两个没有执行完成的异步操作并没有停止,依旧在执行。

关于“JavaScript中Promise的原理是什么及如何使用”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“JavaScript中Promise的原理是什么及如何使用”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript中Promise的原理是什么及如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript中Promise的原理是什么及如何使用

这篇文章主要介绍了JavaScript中Promise的原理是什么及如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中Promise的原理是什么及如何使用文章都会有所收获,下面我们一起
2023-07-05

JavaScript promise的使用方法和原理是什么

这篇“JavaScript promise的使用方法和原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScr
2023-07-06

JavaScript中Promise的简单使用及其原理详解

Promise是ES6最重要的特性之一,今天小编就来带大家一起系统且细致的研究一下Promise的用法以及原理,感兴趣的小伙伴可以学习一下哦
2023-03-23

JavaScript中的Promise如何使用

这篇文章主要介绍了JavaScript中的Promise如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中的Promise如何使用文章都会有所收获,下面我们一起来看看吧。Promise
2023-06-30

JS中Promise的使用及封装方法是什么

这篇文章主要介绍了JS中Promise的使用及封装方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JS中Promise的使用及封装方法是什么文章都会有所收获,下面我们一起来看看吧。Promise 是什么
2023-07-05

Java中ThreadLocal的原理是什么及怎么使用

这篇文章主要介绍“Java中ThreadLocal的原理是什么及怎么使用”,在日常操作中,相信很多人在Java中ThreadLocal的原理是什么及怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Jav
2023-07-06

Zookeeper原理及在Dubbo中使用的方法是什么

这篇文章主要介绍了Zookeeper原理及在Dubbo中使用的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Zookeeper原理及在Dubbo中使用的方法是什么文章都会有所收获,下面我们一起来看看吧
2023-07-05

PHP opcache的原理及使用方法是什么

这篇文章主要介绍了PHP opcache的原理及使用方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP opcache的原理及使用方法是什么文章都会有所收获,下面我们一起来看看吧。PHP项目中,尤其
2023-07-05

Java中AQS的原理及作用是什么

这篇文章主要介绍“Java中AQS的原理及作用是什么”,在日常操作中,相信很多人在Java中AQS的原理及作用是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中AQS的原理及作用是什么”的疑惑有所
2023-06-15

避免async await的使用及原理是什么

这篇文章主要讲解了“避免async await的使用及原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“避免async await的使用及原理是什么”吧!谎言和async/await我
2023-07-02

JavaScript中的回调函数是什么及如何用

今天小编给大家分享一下JavaScript中的回调函数是什么及如何用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.什么是
2023-07-04

C#中+=是什么及如何使用

这篇“C#中+=是什么及如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#中+=是什么及如何使用”文章吧。C#中+=
2023-07-05

JavaScript中的base64编码原理是什么

今天小编给大家分享一下JavaScript中的base64编码原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。bas
2023-07-05

JVM中Synchronized作用及原理是什么

这篇文章主要介绍“JVM中Synchronized作用及原理是什么”,在日常操作中,相信很多人在JVM中Synchronized作用及原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JVM中Synch
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录