Promise全解析

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

Promise是一个JS的异步编程解决方案,解决了传统异步编程回调地狱的问题。

Promise有三种状态:

  • pending(进行中) 
  • fulfilled(已完成)
  • rejected(已失败)

只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

其中pending 为初始状态,状态的变化只有两种:

  1. pending --- fulfilled(异步完成)
  2. pending --- rejected(异步失败)

且一旦状态改变,状态就会凝固,不会在变化了,这就导致了 Promise 一旦建立就会立即执行,无法取消。


Promise 的基本用法

ES6 规定 Promise 是一个构造函数,用来生成 Promise 对象实例。

const promise = new Promise(function(resolve,reject){
    // 异步操作
    if(success){    //异步操作成功
        resolve(value);
    } else{         //异步操作失败
        reject(err);
    }
})

Promise 构造函数接收的参数是一个函数,改函数有两个有JS引擎指定的函数: resolve 函数 和 reject函数

  • resolve 函数有两个作用:
  1. 将 Promise 状态由 pending -- fulfilled (等待态 -- 成功态)
  2. 将异步操作成功的结果value 作为参数传递出去  (由后面讲的 then 方法接收)
  • reject 函数有两个作用:
  1. 将Promise 状态 pending -- rejected (等待态 -- 失败态)
  2. 将异步操作失败的错误信息 err 作为参数传递出去。 (由后面讲到的then / catch 方法接收)

Promise 的三个实例方法 then catch finally

  • 1、Promise.prototype.then()

Promise 实例具有 then方法,也就是说then方法是定义在原型对象上的。

Promise 实例生成后,可以用then方法分别指定 resolve状态和rejected状态的回调函数:获取Promise 内部的异步操作状态。

promise.then({
    function(value){ console.log(value) },  //异步操作成功时(fulfilled态)调用
    function(err){ console.log(err) }       //异步操作失败时(rejected态)调用
})

then 方法可以接收两个回调函数作为参数:

  1. 第一个回调函数在Promise 实例变成 fulfilled 时调用,并获取 resolve 函数传递的参数 value
  2. 第二个回调函数在Promise 实例变成rejected时调用,并获取 reject 函数传递的参数 err

then 方法的返回值是一个新的promise 对象,因此可以 .then 可以链式调用。

 文章来源地址https://www.toymoban.com/news/detail-711186.html

  •  2、Promise.prototype.catch()

Promise 实例的 catch 方法用于指定发生错误时的回调函数,是 .then(null,rejection)的语法糖。

promise.then(function(val){
    console.log(val)    //异步操成功败时(rejected态)调用
}).catch(function(err){
    console.log(err)    //异步操作失败时(rejected态)调用
})

上面代码中,如果 Promise 对象状态变为 fulfilled,则会调用then方法指定的回调函数;

如果异步操作抛出错误,状态就会变为 rejected ,就会调用 catch 方法指定的回调函数。

另外,then方法指定的回调函数,如果运行抛出错误,也会被catch 方法捕获。

promise.then(val => console.log("fulfilled:",val))
       .catch(err => console.log("rejected:",err))
// 等价于
promise.then(val => console.log("fulfilled:",val))
       .then(null,err => console.log("rejected:",err))

如果 Promise 状态已经变成resolved , 再抛出错误时无效的,因为 Promise 的状态一旦改变,就永久保持该状态,不会在变了。

Promise 对象的错误具有冒泡性质,会一直向后传递,直到被捕获为止,也就是说错误总会被下一个catch 语句捕获。

 

  • 3、Promise.prototype.finally()

Promise 实例的 finally 方法用于指定不管状态最终如何,都会执行的函数。是 .then(function,function)(function相同)的语法糖。

promise.finally(message => console.log("状态变化了",message))
// 等价于
promise.then(
    message => console.log("状态变化了",message),
    message => console.log("状态变化了",message)
)
// 无论成功还是失败都会执行

 


 

Promise 的两个静态方法 all 和 race

Promise.all(arr) 方法是挂载在Promise构造函数的静态方法,它传入参数为一个Promise对象数组arr,返回值为一个Promise实例:

  1. 该实例会在Promise对象数组内所有对象的状态变为 fulfilled 时调用内部的 resolve函数;
  2. 该实例在Promise对象数组内任意对象的状态变为rejected时调用 reject函数(reject 函数的参数为第一个错误的promise 对象的err)

有点类似于js里的与操作(&&): 所有表达式为真时返回真,任意表达式为假时返回假。

let p1 = new Promise((resolve,reject)=>{
    resolve('p1-success'),
})
let p2 = new Promise((resolve,reject)=>{
    resolve('p2-success'),
})
let p3 = new Promise((resolve,reject)=>{
    reject('p1-error'),
})

Promise.all([p1,p2,p3]).then(val=>{
    console.log(val)
}).catch(err=>{
    console.log(err)
})

//输出 p1-error

注意:Promise.all() 获得的成功结果的数组里面的数据顺序和 Promise.all() 接收到的数组顺序是一致的。即p1结果在前,即便p1的结果获取比p2要晚,这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用 Promise.all() 毫无疑问可以解决这个问题。

 

Promise.race()

Promise.race(arr) 方法返回一个 promise实例,一旦arr中的某个promise对象解决或拒绝,返回的 promise就会解决或拒绝。
顾名思义,Promise.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('p1-success')
    },1000)
})
let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('p2-success')
    },500)
})
let p3 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject('p3-error')
    },1000)
    
})

Promise.race([p1,p2,p3]).then(val=>{
    console.log(val)
}).catch(err=>{
    console.log(err)
})

//输出 p2-success

 



 

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

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

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

相关文章

  • @Async异步线程:Spring 自带的异步解决方案

            在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调用。         对于异步方法调用,从Spring3 开

    2023年04月24日
    浏览(66)
  • Go异步任务解决方案 Asynq

    今天为大家介绍一个Go处理异步任务的解决方案:Asynq,是一个 Go 库,用于排队任务并与 worker 异步处理它们。它由Redis提供支持,旨在实现可扩展且易于上手。 Asynq 是一个 Go 库,用于对任务进行排队并与工作人员异步处理它们。 Asynq 工作原理的高级概述: 客户端将任务放入

    2024年01月17日
    浏览(41)
  • JS for循环异步解决方案

    JavaScript中的for循环是一种同步操作,它将阻塞代码的执行,直到循环完成。但是,在处理异步操作时,使用同步for循环会导致问题。 为了解决这个问题,可以使用以下两种异步解决方案: 递归是一种有效的解决方案,它可以确保异步操作按照预期执行。以下是使用递归实现

    2024年02月13日
    浏览(39)
  • 【前端面经】JS-异步解决方案

    同步和异步 众所周知, JavaScript 是一门单线程的语言, 单线程就意味着同一时间只能执行一个任务, 当前任务执行结束, 才会执行下一个任务. 这种模式的好处就是执行环境比较单纯, 但坏处也很明显, 一旦有某个任务卡住了, 就会导致整个程序阻塞. 为了解决这个问题, JS将任务的

    2024年02月02日
    浏览(39)
  • 详解JS的四种异步解决方案!

    目录 同步异步的概念 js中异步的应用场景 实现异步的四种方法 1、 回调函数 2、Promise 3、Generator 4、 async/await         「异步编程」 是前端工程师日常开发中经常会用到的技术,也是校招面试过程中常考的一个知识点。         通过掌握 「异步编程」 的四种方式,可

    2024年01月18日
    浏览(43)
  • 【go】异步任务解决方案Asynq实战

    Asynq 是一个 Go 库,一个高效的分布式任务队列。 Asynq 工作原理: 客户端(生产者)将任务放入队列 服务器(消费者)从队列中拉出任务并为每个任务启动一个工作 goroutine 多个工作人员同时处理任务 git库:https://github.com/hibiken/asynq Asynq 使用 Redis 作为消息代理。client 和 se

    2024年02月10日
    浏览(41)
  • 前端异步编程 —— Promise对象

    在前端编程中,处理一些简短、快速的操作,在主线程中就可以完成。 但是,在处理一些耗时比较长以至于比较明显的事情,比如读取一个大文件或者发出一个网络请求,就需要异步编程来实现,以避免只用主线程时造成页面一时无法响应的事情。 以发送网络请求为例,在

    2024年02月08日
    浏览(73)
  • promise及异步编程async await

    ECMAScript 6 新增了正式的 Promise(期约)引用类型,支持优雅地定义和组织异步逻辑。接下来几个版本增加了使用 async 和 await 定义异步函数的机制 JavaScript 是单线程事件循环模型。异步行为是为了优化因计算量大而时间长的操作,只要你不想为等待某个异步操作而阻塞

    2024年02月04日
    浏览(43)
  • JS中的异步编程与Promise

    在了解JavaScript的异步机制之前,我们首先需要理解JavaScript是一种单线程语言。单线程就意味着所有的任务需要按照顺序一次执行,如果前一个任务没有完成,后一个任务就无法开始。这个特性在执行大量或耗时任务时可能会导致阻塞或者界面卡死,这显然是不可取的。 为了

    2024年02月08日
    浏览(51)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包