吊打面试官:promise原理详解

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

什么是promise

Promise是一种异步编程的解决方案。在异步操作中,callback会导致回调地狱的问题,Promise解决了这个问题。

一个Promise代表了一个异步操作,它有三种状态:pending(等待态)、fulfilled(成功态)和rejected(失败态)。当异步操作执行成功后,Promise会从pending转变成fulfilled状态,此时会调用resolve方法并传递返回结果;当异步操作执行失败后,Promise会从pending转变为rejected状态,此时会调用reject方法并传递错误信息。

在使用Promise时,通常会调用其then()方法来处理异步操作的结果,或者调用catch()方法来处理出错信息。同时,Promise还提供了一些静态方法,如Promise.resolve()、Promise.reject()等用于快速创建一个Promise实例。

如何创建promise对象

创建Promise对象有两种方式:

通过Promise构造函数,也称为Promise的手动化管理方式。使用这种方式需要向Promise构造函数传入一个函数,该函数接受两个参数,resolve和reject,分别表示异步操作成功和失败后的回调函数。使用resolve方法可以让Promise状态变为成功态(fulfilled),使用reject方法可以让Promise状态变为失败态(rejected)。

通过静态方法创建一个Promise对象,也称为Promise的自动化管理方式。比如,Promise.resolve()可以创建一个状态为成功的Promise对象,Promise.reject()可以创建一个状态为失败的Promise对象。

下面是两种方式的代码示例:

// 第一种方式,手动管理
let promise = new Promise((resolve, reject) => {
  if (你的判断逻辑) {
    resolve('成功');
  } else {
    reject('失败');
  }
});

// 第二种方式,自动管理
let promise = Promise.resolve('successful');
let promise = Promise.reject('failed');

对于第一种方式,需要手动判断成功还是失败,比如你获取用户信息:

// 定义一个函数,用于获取用户信息
function getUserInfo(userId) {
  // 使用Promise手动管理异步操作
  return new Promise(function(resolve, reject) {
    // 假设获取用户信息是一个异步操作,需要一定时间
    setTimeout(function() {
      // 假设获取到了用户信息
      let user = { id: userId, name: '张三', age: 18 };
      // 判断用户是否存在
      if (user) {
        // 如果存在,使用resolve方法将Promise状态变为成功态
        resolve(user);
      } else {
        // 如果不存在,使用reject方法将Promise状态变为失败态
        reject('用户不存在');
      }
    }, 1000);
  });
}

// 调用getUserInfo函数获取用户信息
getUserInfo('001')
  .then(function(user) {
    // 如果获取用户信息成功,将打印用户信息
    console.log(user);
  })
  .catch(function(error) {
    // 如果获取用户信息失败,将打印错误信息
    console.log(error);
  });

在该例子中,使用Promise手动管理异步操作。在getUserInfo函数中创建了一个Promise对象,将异步操作封装在其中,当异步操作执行成功时,使用resolve方法将Promise状态变为成功态,并传递用户信息,当异步操作执行失败时,使用reject方法将Promise状态变为失败态,并传递错误信息。使用then方法和catch方法分别处理Promise的状态变化,如果Promise状态变为成功态,将打印用户信息,如果Promise状态变为失败态,将打印错误信息。

这样就比较清晰了吧。

关于第二种方式,也给一个例子:

// 模拟一个异步操作函数
function asyncFunction() {
  return new Promise((resolve, reject) => {
    // 模拟一个异步操作,2秒钟后将结果返回
    setTimeout(() => {
      resolve('success');
    }, 2000);
  });
}

// 返回一个已解决的Promise对象,并使用函数返回值作为解决结果
Promise.resolve(asyncFunction())
  .then((value) => {
    console.log('异步操作执行成功', value);
    // 在这里处理异步操作执行成功的情况
  })
  .catch((error) => {
    console.error('异步操作执行失败', error);
    // 在这里处理异步操作执行失败的情况
  });

在这个例子中,我们定义了一个asyncFunction()函数,该函数返回一个Promise对象,在Promise对象的构造函数中使用setTimeout模拟了一个异步操作。然后我们使用Promise.resolve()方法将异步操作函数的返回值转换成一个自动管理状态的Promise对象。最后,我们在使用Promise.resolve()方法返回的Promise对象上使用.then()方法和.catch()方法处理异步操作成功或失败的情况。

使用Promise.resolve()方法的好处在于,如果被传入的参数本来就是一个Promise对象,那么直接返回这个Promise对象,如果不是Promise对象,会自动转换成Promise对象,方便在异步操作逻辑中使用。

无论是哪种方式,创建的Promise对象都将具有pending(等待态)状态,调用resolve或reject方法可以改变其状态,并传递相应的值或错误。

promise的then和catch?

then()catch()方法是Promise对象的原型方法,用于处理异步操作的结果或错误。

then() 方法用来指定当异步操作执行成功时要执行的回调函数。它接受两个参数:第一个参数是成功的回调函数,在异步操作成功时调用;第二个参数是可选的失败的回调函数,在异步操作失败时调用。

catch() 方法用来指定当异步操作执行失败时要执行的回调函数。它只有一个参数,用于指定异步操作失败时要执行的回调函数。

通常情况下,我们会将then()方法和catch()方法串联起来使用,以处理异步操作的返回结果或错误。

以下是一个使用then()方法和catch()方法处理异步操作的例子:

// 模拟一个异步操作函数
function getData() {
  return new Promise((resolve, reject) => {
    // 模拟一个异步操作,2秒钟后将结果返回
    setTimeout(() => {
      resolve({id: 1, name: 'abc'});
    }, 2000);
  });
}

// 处理异步操作的结果
getData()
  .then((data) => {
    console.log('异步操作成功', data);
    // 在这里对异步操作的结果进行处理
  })
  .catch((error) => {
    console.error('异步操作失败', error);
    // 处理异步操作的错误情况
  });

在这个例子中,我们定义了一个getData()函数,该函数返回一个Promise对象,在Promise对象的构造函数中使用setTimeout模拟了一个2秒钟的异步操作。然后,我们使用.then()方法来处理异步操作的结果,如果异步操作成功,就会输出返回的数据对象;否则,我们使用.catch()方法来处理异步操作的错误,如果异步操作失败,就会输出错误信息。

在完整的异步操作逻辑中,我们使用.then()方法和.catch()方法来处理异步操作成功或失败的情况。通过将这两个方法链式调用,可以构造出复杂的异步操作链。

关于then的第二个参数和catch

then()方法和catch()方法是不同的方法,虽然它们都用于处理异步操作的结果或错误。

then()方法有两个参数,第一个参数是当异步操作成功时要调用的回调函数,第二个参数是当异步操作失败时要调用的回调函数。例如:

promise.then(onFulfilled, onRejected); 如果Promise对象在调用then()方法时状态已经变成了已解决(resolved),则会立即调用第一个参数onFulfilled指定的回调函数。如果在调用then()方法时Promise对象的状态还未被解决,onFulfilled回调函数会被存储在一个队列中,并在Promise对象的状态变成已解决时被依次调用。

如果Promise对象在调用then()方法时状态已经变成了已拒绝(rejected),则会立即调用第二个参数onRejected指定的回调函数。如果在调用then()方法时Promise对象的状态还未被解决,onRejected回调函数会被存储在一个队列中,并在Promise对象的状态变成已拒绝时被依次调用。

因此,如果你需要处理Promise对象的成功和失败两种情况,你可以将两个回调函数分别传递给then()方法的两个参数。但是,如果你只需要处理Promise对象的失败情况,你可以将一个回调函数传递给catch()方法,这等价于将该回调函数作为then()方法的第二个参数来调用。例如: promise.then(null, onRejected);promise.catch(onRejected); 是等价的。

finally

finally()方法是Promise对象的原型方法,用于指定不论Promise对象状态如何都要被执行的回调函数,通常用来执行释放资源、清理操作等最终操作。

finally()方法只有一个参数,就是要执行的回调函数。这个回调函数在Promise对象状态变为已解决(resolved)或已拒绝(rejected)时都会被执行,无论如何都会执行。以下是一个使用finally()方法的例子:

function asyncFunction() {
  return new Promise((resolve, reject) => {
    // 模拟一个异步操作,2秒钟后将结果返回
    setTimeout(() => {
      resolve('success');
    }, 2000);
  });
}

// 在异步操作结束后执行清理操作
asyncFunction()
  .then((value) => {
    console.log('异步操作成功', value);
    // 在这里对异步操作的结果进行处理
  })
  .catch((error) => {
    console.error('异步操作失败', error);
    // 处理异步操作的错误情况
  })
  .finally(() => {
    console.log('清理操作已执行');
    // 在这里执行清理操作,无论异步操作成功还是失败都会执行
  });

在这个例子中,我们定义了一个asyncFunction()函数,该函数返回一个Promise对象,在Promise对象的构造函数中使用setTimeout模拟了一个异步操作。然后,我们使用.then()方法来处理异步操作的结果,使用.catch()方法来处理异步操作的错误,使用.finally()方法在异步操作状态变为已解决或已拒绝时执行一些清理操作。

在完整的异步操作逻辑中,我们通常会在finally()方法中释放资源、关闭文件描述符、清理缓存等操作。这些最终操作无论异步操作是否成功、如何结束,都必须执行,保证程序的正确性和资源的安全性。

6.promise的实例方法 then catch finally finally他不管promise 状态是成功还是失败 都会执行的操作。

promise 三个常用静态方法

Promise.all()

Promise.all()方法用于将多个Promise实例包装成一个新的Promise实例,当所有Promise实例都变为fulfilled状态后,才返回新的Promise实例;其中任何一个Promise实例变为rejected状态,都会直接返回rejected状态的Promise实例。

const promise1 = Promise.resolve(1);
const promise2 = 2;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 3);
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values); // [1, 2, 3]
});

Promise.all()方法通常用于处理需要同时获取多个数据的情况,并将这些数据合并为一个结果返回。例如,在一个Web应用程序中,用户在提交订单时需要同时更新订单和用户信息,这时候就可以使用Promise.all()方法一次性向服务器发送两个请求,等待两个Promise都进入fulfilled状态后再进行下一步操作。

另外,Promise.all()方法也可以用于并行处理多个HTTP请求或I/O操作,以提高程序的执行效率。例如,我们从网站中获取多条数据,这些数据都需要通过HTTP请求来获取,在所有Promise进入fulfilled状态后,我们可以将这些数据进行合并,并对它们进行排序、过滤等操作。这样一来,我们就可以在不阻塞主线程的情况下,在较短的时间内获取到多个数据,提高了应用程序的响应速度和用户体验。

除了上述使用场景之外,Promise.all()方法还可以用于多个耗时操作的并行执行和等待,例如读取多个文件、并发执行多个函数等。总之,Promise.all()方法在项目中具有很多实际使用场景,可以帮助我们优化和改进代码的执行效率和用户体验。

Promise.race()

Promise.race()方法同样是将多个Promise实例包装成一个新的Promise实例,但是只要有一个Promise 实例状态发生变化,就将新的Promise实例的状态改变,且终值由第一个完成的 Promise提供。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('promise1 resolved'), 2000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('promise2 resolved'), 1000);
});
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('promise3 resolved'), 3000);
});

Promise.race([promise1, promise2, promise3]).then((value) => {
  console.log(value); // 'promise2 resolved'
});

Promise.race()方法也有许多实际使用场景。它可以用于处理需要快速获取结果的情况,例如,当我们向多个不同的服务器请求同一个资源时,我们可以使用Promise.race()方法来获取最快返回结果的服务器的响应,并忽略其他服务器的响应结果。或者,在一个Web应用程序中,我们需要在指定的时间内获取用户的同步输入和异步请求结果,我们可以使用Promise.race()方法同时监听用户输入事件和请求结果事件,一旦其中有一个事件触发,就可以立即返回响应结果,提高应用程序的响应速度和用户体验。

另外,Promise.race()方法还可以用于处理超时情况,例如,在一个HTTP请求的响应时间超过一定时间后,我们可以使用Promise.race()方法将该请求和一个延迟一定时间的Promise实例包装起来,一旦有一个Promise进入fulfilled状态,就可以立即返回响应结果。如果请求在规定的时间内仍未返回,则将其取消并返回一个错误信息给用户,以提高应用程序的可用性和稳定性。

Promise.any()

Promise.any()方法会对多个Promise进行竞争,直到有一个Promise进入Fulfilled状态,Promise实例返回该Promise的结果。如果所有Promise都进入Rejected状态,则返回失败状态,其中维护Promise及其状态的任何提示返回数组都是必需的。

const promises = [
  Promise.reject(1),
  Promise.reject(2),
  Promise.resolve(3),
];

Promise.any(promises)
  .then((value) => console.log(value))
  .catch((error) => console.log(error)); // 3

如果所有的promise都是reject的,就抛出异常:

const promises = [
  Promise.reject('error 1'),
  Promise.reject('error 2')
];
Promise.any(promises)
  .then((value) => console.log(value))
  .catch((err) => console.log(err));

打印 AggregateError: All promises were rejected

Promise.any()方法可以用于处理多种资源竞争的情况,例如,在一个抢单系统中,多个用户需要争夺同一个订单,系统将同时向多个用户发送请求,并使用Promise.any()方法监听所有请求的状态,一旦有一个用户成功抢到订单,系统就立即返回订单信息并发送通知给该用户,从而提高了用户的参与度和系统的可用性。

除此之外,Promise.any()方法还可以用于指定默认值或备选方案,例如,在一个多语言网站中,我们需要从多个API获取多语言翻译结果,但有些API可能由于网络原因或其他问题无法正常工作,这时候我们就可以使用Promise.any()方法来一次性向多个API发送请求,并设置一个默认值或备选方案,一旦有一个API正常返回翻译结果,就立即返回结果给用户,如果所有API都无法正常工作,则返回默认值或备选方案。文章来源地址https://www.toymoban.com/news/detail-410720.html

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

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

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

相关文章

  • Promise是什么?

    目录 Promise对象的特点 Promise.resolve() Promise.reject() Promise.try() Promise.all() Promise.race() Promise.allSettled() Promise.any() 区分: Promise是异步编程的一种解决方案,它就是一个容器,里面保存着某个未来才会结束的事件的结果,从语法上说,Promise就是一个对象,从他可以获取异步操作的

    2024年02月05日
    浏览(31)
  • 什么是promise?

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 promise是es6新增的API,用于异步任务的封装 promise用法1:封装ajax请求,在ajax回调函数之外使用请求数据 *因为异步函数任务没有

    2023年04月12日
    浏览(32)
  • 什么是Promise对象?它的状态有哪些?如何使用Promise处理异步操作?以及 async、await

    前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一

    2024年02月11日
    浏览(46)
  • 前端面试:【异步编程】Callback、Promise和Async/Await

    嗨,亲爱的JavaScript探险家!在JavaScript开发的旅程中,你会经常遇到异步编程的需求。为了处理异步操作,JavaScript提供了多种机制,包括Callbacks、Promises和Async/Await。本文将深入介绍这些机制,让你能够更好地处理异步任务。 1. Callbacks:传统的异步方式 Callbacks是JavaScript中最早

    2024年02月11日
    浏览(85)
  • promise的原理和几种使用方法

    promise概念 Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果,其实是一个构造函数,自己身上有all、reject、resolve,race这几个方法,原型上有then、catch, finally 等方法

    2023年04月09日
    浏览(36)
  • js中的promise详解

           Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有以下两个特点: (1)对象的状态不受外界影响。 (2)一旦状态改变了就不会再变,也就是说任何时候Promise都只有一种状态。    

    2024年02月02日
    浏览(44)
  • 异步同步化( Promise 详解)

    ES 6 Promise的用法 一 、为什么要使用Promise “ 回调地狱 ”这个词,不知道大家听过没有,就是异步调用 获取到结果 后, 为下一个异步函数提供 参数 ,所以就会一层一层的出现回调里面 嵌入回调,导致层次很深,代码维护起来特别的复杂,看一下下面的小案例大家就知道什

    2024年02月16日
    浏览(47)
  • Promise、Async/Await 详解

            Promise是抽象异步处理对象以及对其进行各种操作的组件。Promise本身是同步的立即执行函数解决异步回调的问题, 当调用 resolve 或 reject 回调函数进行处理的时候, 是异步操作, 会先执行.then/catch等,当主栈完成后,才会去调用执行resolve/reject中存放的方法。      

    2024年02月14日
    浏览(39)
  • ES6 Promise 详解

    目录 一、Promise基本介绍 二、Promise实现多次请求         1.传统Ajax方式实现多次请求 :              1.1 json数据准备             1.2 JQuery操作Ajax         2.使用ES6新特性Promise方式 :  三、Promise代码重排优化         1.问题分析 :          2.代码优化 :              2

    2024年02月08日
    浏览(36)
  • 前后端交互系列之promise详解

    我们在前端学习中遇见果大量的回调函数,很多回调函数聚在一起会使得逻辑混乱以及代码可读性差。于是有了promise这一门技术。 promise在面试中也是非常重要的一个知识点。本篇文章涵盖了promise日常使用中的基本操作。希望可以给读者带来帮助。另外如果需要提升的话,可

    2024年02月04日
    浏览(35)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包