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

通过代码实例带你了解Promise

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

北京

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

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

看不清楚,换张图片

免费获取短信验证码

通过代码实例带你了解Promise

本篇文章通过多段代码实例带大家了解 Promise 的基础用法,以及更进一步掌握 Promise 异步存取的思想。

通过代码实例带你了解Promise

之前一直有听说 Promise 的威名,但是总觉得是个较为深奥的东西,有点畏难而没能真正地去了解。最近看了李立超老师在B站传的 Node.js 的视频,感觉讲的很清晰,自己在这做进一步的梳理。

先来看一个问题

我们都知道 JavaScript 是单线程运行的,所以如果遇到一个数据需要过段时间才能获取到的情况,就会形成阻塞导致后面的代码也无法执行,而这相当致命,比如下面代码

function sum(a, b) {
    const begin = Date.now();
    while(Date.now() - begin < 10000) {

    }
    return a+b;
}

console.log(sum(1,2));
console.log("1");

中间的 while 语句经历了10秒的循环,最终才分别打印出了 3 和 1

然而我们希望的是允许3在10秒后再打印出来,但是1得先打印出来

这里我们就用到了setTimeout,修改代码如下

function sum(a, b) {
    setTimeout(() => {
        return a+b;
    },10000)
}

console.log(sum(1,2));
console.log("1");

运行一下可以看到1确实瞬间被打印出来了,但是本该打印3的位置是undefined

image.png

原因在于此时的console.log同样没有等待setTimeout走完,无法接收到10秒后的数据

所以为了能够接收到这个10秒后的数据,我们可以采用回调函数的方式

function sum(a, b, callback) {

    setTimeout(() =>{
        callback(a+b);
    }, 10000)

}

sum(1,2,(result) => {
    console.log(result);
});
console.log("1");

传入了一个能够接收 a+b 为参数的回调函数 (result) => {console.log(result);}

所以在10秒后会执行这个回调函数,进行打印,结果如下

image.png

这样我们就初步解决了这个问题,一个需要延时获取的数据在其他代码先执行后再被获取。

然而 Promise 还没出现,这就涉及了另一个需要改进的地方

回调地狱

这是个乍一听很唬人的称呼,实际上就是多层回调函数的嵌套导致的不利于阅读和调试的情况。

比如此时我们想要多次调用这个sum函数,要在得到1+2的结果后,再获得 1+2+3,1+2+3+4 这些结果

所以我们得在sum传入的回调函数里再多次调用sum进行嵌套,如下

sum(1,2,(result) => {
    sum(result, 3, (result) => {
        sum(result, 4, (result) => {
            console.log(result);
        })
    })
});

image.png

这种类似金字塔的结构可读性差且不好调试,被称作回调地狱。

所以此时终于到了Promise出场的时候,它的出现解决了回调地狱的问题。

Promise 是什么

在使用Promise解决回调地狱的问题前,先来大致地了解一下什么是Promise。

目前我对它的判断是,Promise 是一个用于存取异步数据的对象。

首先来看一下空的 Promise 打印出来会是什么

const promise = new Promise(()=>{});

image.png

其中最关键的就是 PromiseState 和 PromiseResult 两个值,之后会详细展开,这里只要知道Promise中有着这两个属性即可。

接着来看一下 promise 存数据的过程,最关键的就是要知道有 resolve 和 reject,比如下面代码

const promise = new Promise((resolve, reject) => {
    const flag = true;
    if (flag) {
        resolve("resolve datas");
    } else {
        reject("reject data");
    }
})

此时flag为true,所以执行的是resolve的存储,得到的结果如下

image.png

而当我们把flag改为false,执行reject的存储时,得到的结果如下

image.png

现在是解释上面两个属性的时候了,

  • 当 promise 没有存储数据时,PromiseState 的值为 pending,PromiseResult的值为 undefined
  • 当 promise 使用 resolve 存储数据时,PromiseState 的值为 pending,PromiseResult的值为 相应存储值
  • 当 promise 使用 reject 存储数据时,PromiseState 的值为 rejected,PromiseResult的值为相应存储值

既然存有两种类型,读自然也要分两种

当我们读取promise中的数据时,我们需要使用如下的结构

promise.then(result => {
    console.log(result);
}, reason => {
    console.log(reason);
})

如果数据存在resolve中,result会返回结果,如果存在reject中,reason会返回结果。

使用Promise解决回调地狱

在初步了解了Promise后,会发现目前Promise能做的事,使用回调函数也能完成。

所以最主要的还是Promise解决了回调地狱,比如之前的问题,可以写成这种形式

function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a+b);
        }, 1000);
    })
}

sum(1,2)
    .then(result => sum(result,3))
    .then(result => sum(result,4))
    .then(result => {
        console.log(result);
    })

promise 通过then方法进行读取后,是个新的Promise对象,比如我们可以打印一下

function sum(a, b) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a+b);
        }, 1000);
    })
}

console.log(sum(1,2)
    .then(result => sum(result,3)))

image.png

所以这也就给了我们能多次调用then方法的基础。

而这也就解决了回调地狱的问题。

小结

Promise 是一个可以存取异步数据的对象,通过resolvereject来存储数据,可以通过then来读取数据

至于其他的.catch .finally .race .any .all 这些方法就不再多作赘述,详细的见文档

【推荐学习:javascript高级教程】

以上就是通过代码实例带你了解Promise的详细内容,更多请关注编程网其它相关文章!

免责声明:

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

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

通过代码实例带你了解Promise

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

下载Word文档

猜你喜欢

通过代码实例带你了解Promise

本篇文章通过多段代码实例带大家了解 Promise 的基础用法,以及更进一步掌握 Promise 异步存取的思想。
2023-05-14

一篇文章带你了解Go到C的代码转换过程

随着软件开发的迅速发展,越来越多的编程语言涌现出来,每一种语言都有其独特的特点和优势。在开发过程中,有时候我们会面临将一个项目从一种编程语言转换成另一种编程语言的情况。本文将以Go语言转换为C语言为例,带您深入了解这一过程,并给出具体的代码
一篇文章带你了解Go到C的代码转换过程
2024-03-07

简单实例带你了解Python的编译和执行全过程

python是一种解释型的编程语言,所以不像编译型语言那样需要显式的编译过程。然而,在Python代码执行之前,它需要被解释器转换成字节码,这个过程就是Python的编译过程,还不知道的朋友快来看看吧
2023-05-17

通过python连接Linux命令行代码实例

这篇文章主要介绍了通过python连接linux命令行代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下#!/usr/bin/python # -*- coding: utf
2022-06-04

通过jstack分析解决进程死锁问题实例代码

刚才用jstack解决了一个进程死锁的问题——其实早就解决了,也知道原因,只是一直没找到死锁的位置,不太甘心而已。流程大致如下:(0)环境要求,JDK1.6及以上(1)先找到进程的PID,Windows下,打开进程管理器,按照名字排序,可以
2023-05-30

Android中通过反射实现圆角ImageView代码实例

private void init(){paint = new Paint(Paint.ANTI_ALIAS_FLAG); roundRect = new RectF(0, 0, getWidth() , getHeight());r
2022-06-06

Android通过Webservice操作sqlserver数据库实例代码

首页在AndroidManifest.xml中添加访问数据库权限 2022-06-06

shell通过正则匹配ip地址实例代码

前言 在运维场景下,我们经常需要在服务器上用正则表达式来匹配IP地址。 shell和其它编程语言一样,也可以使用正则分组捕获,不过不能使用 $1或\1这样的形式来捕获分组,可以通过数组${BASH_REMATCH}来获得,如${BA
2022-06-04

Java通过URL类下载图片的实例代码

这篇文章主要介绍了Java通过URL类下载图片,文中结合实例代码补充介绍了java通过url获取图片文件的相关知识,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2023-02-22

android 通知Notification详解及实例代码

android Notification实例详解 1.使用Builder模式来创建2.必须要设置一个smallIcon,还可以设置setTicker3.可以设置 setContentTitle,setContentInfo,setConte
2022-06-06

Android通过手势实现的缩放处理实例代码

网络上传言HTC的HERO-ROM支持多点触摸的论证大多源于浏览网页和图片时,能像IPhone一样通过手势来控制页面的大小。下面的例子是利用现有的API实现HERO浏览图片和网页的缩放功能。 主要原理是onTouchEvent事件中的参数
2022-06-06

android通过okhttpClient下载网页内容的实例代码

有时候我们需要通过自己的缓存机制来缓存网页内容,当没有网的时候显示本地的缓存,当有网的时候取最新的继续缓存到本地。主要机制:通过AsyncTask异步AsyncTask请求,将得到的response.body()缓存起来。主要代码如下://
2023-05-30

Android下通过httpClient发送GET和POST请求的实例代码

代码如下: public class HttpUtil { public static String sendDataByHttpClientGet(String path,String name,String pass)
2022-06-06

编程热搜

目录