JavaScript 异步解决方案 Promise 全解析(转载)

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

 

Promise 是什么?

Promise 是一个 JS 的异步编程解决方案,解决了传统异步编程回调地狱的问题。 从语义上来说:Promise 是一个向外部传达异步编程操作消息的对象。

Promise 的三种状态

JS里一个promise可以有以下几种基本状态:

  1. nothing happened yet
  2. "locked in" to another promise
  3. fulfilled
  4. rejected

其中{1,2}为pending,{3,4}为settled,{2,3,4}为resolved,{1}为unresolved。

 

Promise 对象表示一个异步操作,拥有三种状态:

  1. pending(进行中)
  2. fulfilled(已完成)
  3. 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 方法可以接收两个回调函数作为参数:

第一个回调函数在 promise 实例变为 fulfilled 时调用,并获取 resolve 函数传递的参数 value。 第二个回调函数在 promise 实例变为 rejected 时调用,并获取 reject 函数传递的参数 err。 then 方法的返回值是一个新的 Promise 对象,因此可以 .then 可以链式调用

2. Promise.prototype.catch()

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

promise
  .then(function (val) {
    console.log(val); //异步操作成功时(fulfilled 态)调用
  })
  .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

1. Promise.all()

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

该实例会在 Promise 对象数组 内所有对象的状态变为 fulfilled 时调用内部的 resolve 函数; 该实例在 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() 毫无疑问可以解决这个问题。

2. 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


作者:Prayx
链接:https://juejin.cn/post/6862929170390450183
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章来源地址https://www.toymoban.com/news/detail-711190.html

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

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

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

相关文章

  • [javascript核心-04]彻底弄懂Promise异步编程

    本文github地址:JavaScript_Interview_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士 1.1. 快速上手 01快手上手.js 02.若传入的是另一个promise对象,则状态由传入的promise对象决定 03.若传入了一个实现了 then 方法的对象,则执行该then方法且由此方法

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

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

    2024年02月02日
    浏览(38)
  • Go异步任务解决方案 Asynq

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

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

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

    2024年02月13日
    浏览(38)
  • 【go】异步任务解决方案Asynq实战

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

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

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

    2024年01月18日
    浏览(42)
  • Redux异步解决方案 1. Redux-Thunk中间件

    简单介绍一下 thunk ,这是一个中间件,是解决 redux 异步问题产生的。我们都知道,在使用 redux 的时候,通过 dispatch 一个 action 发生到 reducer 然后传递给 store 修改状态 一系列都是同步的,那如果说我 dispatch 一个 action 这个 action 帮我请求一下接口数据,你发现接口请求是异步

    2024年02月09日
    浏览(50)
  • 使用aiohttp异步调用API+request上传文件中文文档名乱码解决方案

    有时候在调用需要用异步调用API接口。在python中有很多框架,比如 asyncio , Celery , Quart 等。这里我选择了 asyncio 。Python 3.5以上版本内置了 asyncio 库,可以用来编写单线程的并发代码。可以使用此库与 aiohttp 结合来发送异步HTTP请求。 参数为JSON 需要同时上传文件和JSON参数

    2024年02月04日
    浏览(45)
  • [javascript核心-09] 彻底解决js中的类型检测方案

    typeof 基于数据类型的值(二进制)进行检测 返回结果为字符串 typeof NaN 结果为 number typeof null 结果为 Object .对象存储以 000 开头,而 null 也是如此。 typeof 不能细分对象,结果都是 Object typeof function(){} 结果为 function instanceof 检测某个构造函数是否出现在某实例的原型链上 返回结

    2024年02月16日
    浏览(54)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包