javascript中Promise使用详解

目录
  • 一、首先,要知道为什么要用Promise语法?
  • 二、接着,来了解一下回调地狱(Callback Hell)
  • 三、最后,也是本章的重头戏,Promise的基本使用
    • (一) resolve函数
    • (二) rejected函数
    • (三)Promise的API
      • 1. then
      • 2. catch
      • 3. finally
      • 4. Promise.all
      • 5. Promise.race
  • 四、最后

前言:

做过前端开发的都知道,JavaScript是单线程语言,浏览器只分配给JS一个主线程,用来执行任务,但是每次一次只能执行一个任务,这些任务形成一个任务队列排队等候执行;但是某些任务是比较耗时的,如网络请求,事件的监听,以及定时器,如果让这些非常耗时的任务一一排队等候执行,那么程序执行效率会非常的低,甚至会导致页面假死。因此,浏览器为这些耗时的任务开辟了新的线程,主要包括http请求线程、浏览器事件触发线程、浏览器定时触发器,但是这些任务都是异步的,这就涉及到了前端开发的异步回调操作处理,前端处理异步回调操作用到的就是Async/Await和Promise。

而且在前端相关的面试的时候,面试官一般都会问到关于Promise相关的使用问题,甚至在笔试中也会出一些关于Promise和setTimeout的执行结果,这说明Promise的使用对于前端开发来说是非常重要的一个知识点。那么本篇博文就来分享一下关于Promise的使用相关的知识点。

一、首先,要知道为什么要用Promise语法?

在介绍Promise之前,首先来了解一下JavaScript的特性。搞前端开发的都知道JS是一个传统的单线程编程,它里面的程序运行都是同步的,只有一个主线程,但是随着技术的发展,为了解决前期的缺陷,引入了异步思想,也就是一个异步过程的执行将不再与原有的序列有顺序关系,这就解决了同步执行引起的执行效率不高的缺陷。用一句话解释:异步就是从主线程发射一个子线程来完成任务。

再来了解一下Promise,Promise是ES6新增加的,它是一个由ES6提供的类,其主要目的就是很好的处理复杂的异步任务,但是它不是任何浏览器都能支持,比如一些旧版本的浏览器就不支持,只有苹果的Safari10和Windows的Edge14版本以上浏览器才开始支持ES6特性的。

Promise作为替代回调函数执行,作为异步操作的处理方法;是JS异步执行时候,回调函数嵌套回调函数的这一问题的解决方法,Promise更简洁地控制函数执行流程。Promise对象其实表示是一个异步操作的最终成败,以及结果值,也就是一个代理值,是ES6中的一种异步回调解决方案。

Promise对象代理的值其实是未知的,状态是动态可变的,因此Promise对象的状态有三种:进行中、结束、失败,它运行的时候,只能从进行中到失败,或者是从进行中到成功。使用Promise对象只要是通过同步的表达形式来运行异步代码。

  • pending:初始状态,既不成功,也不失败;
  • fulfilled:操作成功结束;
  • rejected:操作失败。

怎么构造Promise?这里简单举一个构造Promise的示例:

new Promise(function (resolve, reject) {

   // 要做的事情...

});

通过上面新构造一个Promise 对象好像并没有看出它是怎样很好的处理复杂的异步任务的,那么接下来就是Promise的核心操作。

二、接着,来了解一下回调地狱(Callback Hell)

回调地狱也叫回调嵌套或者函数混乱的调用,通俗点讲就是:需要发送三个网络请求,第三个请求依赖第二个请求的结果,第二个请求依赖第一个请求的结果。不断增加的嵌套使用。

回调函数的弊病:

开发者阅读起来很费神、吃力,不利于排查错误,更不能直接return,等等。如:

setTimeout(() => {
console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
},3000)
},2000)
},1000)

三、最后,也是本章的重头戏,Promise的基本使用

Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数,也就是Promise的构造函数里面有两个参数:resolve和reject,该两个参数表示的是异步操作的结果,也就是Promise成功或失败的状态。

当 Promise 被构造时,起始函数会被异步执行;resolve 和 reject 都是函数,其中调用 resolve 代表一切正常,reject 是出现异常时所调用的。

  • ①异步操作成功,调用resolve函数,将Promise对象的状态改为fulfilled。
  • ②异步操作失败,调用rejected函数,将Promise对象的状态改为rejected。

举一个使用例子,比较规范的写法是把Promise封装到一个函数里然后同时返回一个Promise,如下所示:

const delay = (millisecond) => {
return new Promise((resolve, reject)=>{
if (typeof millisecond != 'number') reject(new Error(‘必须是number类型'));
setTimeout(()=> {
resolve(`延迟${millisecond}毫秒后输出`)
}, millisecond)
})
}

上述例子可以看到Promise有两个参数:resolve和reject。resolve:将异步的执行从pending(请求)变成了resolve(成功返回),是个函数执行返回;reject:见名知意为“拒绝”,从请求变成了"失败",是函数可以执行返回的一个失败结果,推荐返回一个错误new Error(),这样做更加清晰明了,更加规范。

(一) resolve函数

若传入的是非Promise,基本数据类型的数据,则返回成功的Promise;若传入的是Promise,则该对象的结果就决定了resolve的返回结果值。

let obj =new Promise((resolve,reject)=>{
resolve(‘yes');
});

//1.若传入的是非Promise,基本数据类型的数据,则返回成功的Promise。

let p1= Promise.resolve('123')

//2.若传入的是Promise,则该对象的结果就决定了resolve的返回结果值。

let p2 = Promise.resolve(obj);

//3.嵌套使用

let p3 = Promise.resolve(Promise.resolve(Promise.resolve('abc')));
console.log(p3);

(二) rejected函数

Promise.prototype.reject,始终返回的是失败的Promise

let p = Promise.reject(123123);
let p2 = Promise.reject('abc');
let p3 = Promise.reject(Promise.resolve('ok'));
console.log(p3);

(三)Promise的API

Promise的API里面常用的几个方法有:then、catch、finally、all、race等,具体的使用方法下面一一道来。

1. then

then指定成功或失败的回调到当前的Promise。then里面拿到的Promise resolve里面的数据,并返回一个Promise继续提供使用;then方法返回的结果由then指定回调函数决定。

实例如下所示:

let p=new Promise((resolve,reject)=>{
resolve(‘yes')
})

p.then(value=>{
console.log(value) //这里的value就是上面的yes
},reason=>{
console.error(reason)
})

2. catch

catch指定失败的回调,返回的是失败的结果。

实例如下所示:

let p =new Promise((resolve,reject)=>{
reject('失败!');
})

p.then(value=>{},reason=>{
console.error(reason);
})

p.catch(reason=>{
console.error(reason)
})

3. finally

finally用来进行收尾工作,无论Promise的状态成功和失败与否,当执行完回调函数之后,都会去finally寻找最后的回调函数来执行。

实例如下所示:

request.finally(function(){
// 最后,而且一定会执行的代码
})

4. Promise.all

在多个Promise任务一起执行的时候,若全部成功,则返回一个新的Promise,若其中有一个失败,则返回失败的Promise对象。

实例如下所示:

let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(‘yes');
}, 1000);
});

let p2 = Promise.resolve('ok');
let p3 = Promise.reject('Oh no');

//所有的
let result = Promise.all([p1, p2, p3]);
console.log(result);

5. Promise.race

在多个Promise任务同步执行的时候,返回最先结束的Promise任务结果,无论最后是成功还是失败,通俗点将:先到先得。

实例如下所示:

let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(‘yes');
}, 1000);
});

let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok');
}, 500);
});

let result = Promise.race([p1, p2]);
console.log(result); //p2 ok

四、最后

通过本文关于在前端JS开发中对Promise使用详解,是不是已经完全掌握它的使用以及原理呢?如果读者很好的掌握了本篇内容,那么以后不管是在实际开发过程中还是求职面试中,涉及到Promise的知识点都会游刃有余,Promise的重要性这里不再赘述

到此这篇关于javascript中Promise使用详解的文章就介绍到这了,更多相关javascript中的Promise内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • node.js Promise对象的使用方法实例分析

    本文实例讲述了node.js Promise对象的使用方法.分享给大家供大家参考,具体如下: Promise对象是干嘛用的? 将异步操作以同步操作的流程表达出来 一.Promise对象的定义 let flag = true; const hello = new Promise(function (resolve, reject) { if (false) {//异步操作成功 resolve("success"); } else { reject("error");

  • js使用Promise实现简单的Ajax缓存

    业务场景 在不少业务场景下,我们需要实现简单的请求缓存(即某个请求只发起一次请求),例如上传 Token 的获取.获取配置的接口等. 这些接口可以通过 Promise 实现简单的缓存并能够控制更新,而不需要另外引入缓存层. 示范代码 用七牛上传作例子,一般我们会把七牛上传封装为一个单独的 Upload 组件,外部只需要调用组件,而 token 的获取封装到组件内部实现. //Upload.vue let fetchToken = null; export default { data() { r

  • JavaScript使用promise处理多重复请求

    一.为什么要写这个文章? 处理重复请求的文章想必大家也看过了很多,大多数都是分为在response返回之前发现重复请求就return掉的和使用节流/防抖来间接规避用户频繁操作两种版本的.最近在使用的过程的中,发现这两个版本在某些场景下还是有些局限性. 二.问题场景 如图,我这个h5的页面,顶部和底部都要显示这个名片组件.这些名片的信息是通过一个接口来获取的,当这个组件在当前页面被初始化时,就会发生两次重复的请求. 这时会面临几个抉择: 1. 不对重复请求做任何处理. 缺点1:造成不必要的资源浪费

  • JavaScript异步编程之Promise的初步使用详解

    1. 概述 Promise对象是ES6提出的的异步编程的规范.说到异步编程,就不得不说说同步和异步这两个概念. 从字面意思理解同步编程的话,似乎指的是两个任务同步运行,如果这样理解就错了(至少笔者再没有接触到这个概念的时候有这种误解).同步和异步指的是代码指定执行的顺序(结构化编程范式的执行顺序总是由上至下,由前往后的),如果执行的顺序与代码的相同,就是同步:如果不同,就是异步. 最初,操作系统都是基于命令行的,所有的的语言设计出来也天然是同步的语句,在这种情况下,也不需要异步编程.但是很快,图

  • 详解在微信小程序的JS脚本中使用Promise来优化函数处理

    在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入Promise确实能够很好的解决异步回调函数的可读性等问题,同时也使得我们调用的时候代码简洁一些,本文介绍如何在小程序的JS代码里面使用Promise来封装一些函数的做法. 1.小程序传统的回调处理 例如我们生成一个小程序,里面的app.js里面就自动带有一个getUserInfo的函数,这个是使用

  • JS 中使用Promise 实现红绿灯实例代码(demo)

    要求 使用promise 实现红绿灯颜色的跳转 绿灯执行三秒后 黄灯执行四秒后 红灯执行五秒 html 实现如下: <ul id="traffic" class=""> <li id="green"></li> <li id="yellow"></li> <li id="red"></li> </ul> 定义一个

  • JavaScript中Promise的使用详解

    Promise是ES6中的函数,规范了如何处理异步任务的回调函数,功能类似于jQuery的defferred.简单说就是通过promise对象的不同状态调用不同的回调函数.目前IE8及以下不支持,其他浏览器都支持. promise对象的状态,从Pending转换为Resolved或Rejected之后,这个promise对象的状态就不会再发生任何变化. 使用步骤: var promise = new Promise(function(resolve, reject) { // 异步任务,通过调用

  • javascript中Promise使用详解

    目录 一.首先,要知道为什么要用Promise语法? 二.接着,来了解一下回调地狱(Callback Hell) 三.最后,也是本章的重头戏,Promise的基本使用 (一) resolve函数 (二) rejected函数 (三)Promise的API 1. then 2. catch 3. finally 4. Promise.all 5. Promise.race 四.最后 前言: 做过前端开发的都知道,JavaScript是单线程语言,浏览器只分配给JS一个主线程,用来执行任务,但是每次

  • JavaScript实现Promise流程详解

    目录 构造函数 then 和 catch方法 解决异步问题 all和race方法 构造函数 首先我们来看一下我们是如何使用promise的,我们在实例化对象是这么使用的: let p1 = new Promise((resolve, reject) => { let random = Math.floor(Math.random() * 10); if (random > 4) { resolve('sucess') } else { reject('erro') } }) 所以我们在创建我们

  • javascript中正则表达式语法详解

    好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要是以前本人一遇到写正则的需求就开始头大,头疼,网上剽窃,东拼西凑,反正就是各种不适应,所以我打算系统的把正则表达式看一遍,一来是自己有所提升,这一块知识点的查漏补缺,二来是给大家分享一下.好了,下面我们直接进入主题: 正则是匹配字符串特定模式的一种表达式,官方是这样说的,但我的理解不外乎就是匹配字符

  • javascript中clone对象详解

    开发中,打断对象间的引用关系,只想下个副本的情况无处不在,clone一个对象就在所难免了. JavaScript中,简单的方法就是用JSON函数,将对象stringify成字符串,再parse成一个新对象.要么就是从网上搜个代码,开源社区里面clone的代码还是有不少的. 代码虽然可以找得到,但,东西永远是别人的,动手学着码永远是个不变的主题. 自己写了两个克隆的函数: cloneOwn:克隆自定义对象的自有属性,不包括继承的属性,属性可以是基本数据类型和数组,自定义的对象,可以制定要克隆的属性

  • JavaScript中闭包的详解

    闭包是什么 在 JavaScript 中,闭包是一个让人很难弄懂的概念.ECMAScript 中给闭包的定义是:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量. 是不是看完这个定义感觉更加懵逼了?别急,我们来分析一下. 闭包是一个函数 闭包可以使用在它外面定义的变量 闭包存在定义该变量的作用域中 好像有点清晰了,但是使用在它外面定义的变量是什么意思,我们先来看看变量作用域. 变量作用域 变量可分为全局变量和局部变量.全局变量的作用域就是全局性的,在 js

  • 比较全面的C 、Java、JavaScript中的正则表达式详解

    什么是正则表达式? 正则表达式(Regular Expression) 就是用某种模式去匹配一类字符串的公式.如你要在一篇文章中查找第一个字是"罗"最后一个字是"浩"的三个字的姓名,即"罗 * 浩":那么"罗 * 浩"就是公式,也称作 模式(Pattern) ,这篇文章就是 要匹配的串( 或叫文本 text) .再如,你要检查输入的一个字符串是否是 126 邮箱的格式,你得制定一个规则去查检,这种规则就是正则表达式. 从入门开

  • javascript中new关键字详解

    和其他高级语言一样javascript中也有new关键字,我们以前认知的new是用来创建一个类的实例对象,但在js中万物皆是对象,为何还要new关键字呢,其实js中new关键字不是用来创建一个类的实例对象,而是用于继承. 接下来,本文将带你一起来探索JS中new的奥秘... function Animal(name){ this.name = name; } Animal.color = "black"; Animal.prototype.say = function(){ conso

  • javascript中this关键字详解

    不管学习什么知识,习惯于把自己所学习的知识列成一个list,会有助于我们理清思路,是一个很好的学习方法.强烈推荐. 以下篇幅有点长,希望读者耐心阅读. 以下内容会分为如下部分: 1.涵义 1.1:this涵义 1.2:this指向的可变性 2.使用场合 2.1:全局环境 2.2:构造函数 2.3:对象的方法 3.使用注意点 3.1:避免多层嵌套this 3.2:避免数组处理方法中的this 3.3:避免回调函数中的this 1.涵义 1.1:this涵义 在我写的一篇关于 构造函数与new关键字

  • javascript中闭包(Closure)详解

    在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中. var fun = function(){ console.log("平底斜"); } function fun(){ var n=10; function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //11 我们把上面第二段代码稍微修改下: var n=10; function fun(){ function son(){

  • Javascript中的 “&” 和 “|” 详解

    一.前言: 在文章开始之前,先出几个题目给大家看看: var num1 = 1 & 0; console.log(num1); // 0 var num2 = 'string' & 1; console.log(num2); // 0 var num3 = true & 1; console.log(num3); // 1 var num4 = undefined | false; console.log(num4); // 0 var num5 = undefined | tru

随机推荐