promise看这一篇就够了

简介: promise看这一篇就够了

前言



本片文章博主主要从介绍promise->用法->手写实现->常用API->特性->适用场景六个方面给大家展开讲解

感兴趣的不妨看下去吧 记得三联支持作者


介绍



Promise是JavaScript中用于处理异步操作的一种机制。它解决了传统回调函数嵌套(callback hell)带来的可读性差、错误处理困难等问题,使得异步代码更加清晰、可维护。


一个Promise代表了一个异步操作的最终完成或失败,并且可以返回一个值。它有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一旦Promise的状态变为fulfilled或rejected,就称为“settled”(已定型)。


在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('得到最终结果: ' + finalResult);
    }, failureCallback);
  }, failureCallback);
}, failureCallback);


阅读上面代码,是不是很难受,上述形成了经典的回调地狱

现在通过Promise的改写上面的代码

doSomething().then(function(result) {
  return doSomethingElse(result);
})
.then(function(newResult) {
  return doThirdThing(newResult);
})
.then(function(finalResult) {
  console.log('得到最终结果: ' + finalResult);
})
.catch(failureCallback);


瞬间感受到promise解决异步操作的优点:

  • 链式操作减低了编码难度
  • 代码可读性明显增强


下面我们正式来认识promise:

状态

promise对象仅有三种状态

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)
    特点
  • 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
  • 一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果

流程

认真阅读下图,我们能够轻松了解promise整个流程

f78bc16e13464ccaa17351023e7406a5.png


用法



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

const promise = new Promise(function(resolve, reject) {});


Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject

  • resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
  • reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”


手写实现一个promise



class MyPromise {
  constructor(executor) {
    this.status = 'pending'; // Promise的状态,初始为pending
    this.value = undefined; // Promise的值,默认为undefined
    this.callbacks = []; // 存储then回调函数的数组
    const resolve = (value) => {
      if (this.status === 'pending') {
        this.status = 'fulfilled'; // 改变Promise的状态为fulfilled
        this.value = value; // 设置Promise的值
        // 依次执行then回调函数
        this.callbacks.forEach((callback) => {
          callback.onFulfilled(value);
        });
      }
    };
    const reject = (reason) => {
      if (this.status === 'pending') {
        this.status = 'rejected'; // 改变Promise的状态为rejected
        this.value = reason; // 设置Promise的值
        // 依次执行then回调函数
        this.callbacks.forEach((callback) => {
          callback.onRejected(reason);
        });
      }
    };
    try {
      executor(resolve, reject); // 执行executor函数,并传入resolve和reject作为参数
    } catch (error) {
      reject(error); // 如果executor执行出错,则将错误信息传递给reject
    }
  }
  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      const handleCallback = (callback) => {
        try {
          const result = callback(this.value); // 执行回调函数,并传入Promise的值
          if (result instanceof MyPromise) {
            result.then(resolve, reject); // 如果回调函数返回的是一个Promise,使用then继续处理
          } else {
            resolve(result); // 否则将回调函数的返回值作为新Promise的值
          }
        } catch (error) {
          reject(error); // 如果回调函数执行出错,则将错误信息传递给reject
        }
      };
      if (this.status === 'pending') {
        this.callbacks.push({
          onFulfilled: (value) => handleCallback(onFulfilled),
          onRejected: (reason) => handleCallback(onRejected)
        });
      } else if (this.status === 'fulfilled') {
        handleCallback(onFulfilled);
      } else if (this.status === 'rejected') {
        handleCallback(onRejected);
      }
    });
  }
  catch(onRejected) {
    return this.then(null, onRejected); // catch方法实际上是then方法的语法糖,只接受onRejected回调
  }
  static resolve(value) {
    return new MyPromise((resolve) => resolve(value)); // 创建一个状态为fulfilled的Promise,并将指定的值传递给resolve
  }
  static reject(reason) {
    return new MyPromise((resolve, reject) => reject(reason)); // 创建一个状态为rejected的Promise,并将指定的原因传递给reject
  }
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      const results = []; // 存储每个Promise的结果
      let count = 0; // 记录已完成的Promise数量
      promises.forEach((promise, index) => {
        promise.then((value) => {
          results[index] = value;
          count++;
          if (count === promises.length) {
            resolve(results); // 所有Promise都完成时,将结果传递给resolve
          }
        }, reject);
      });
    });
  }
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      promises.forEach((promise) => {
        promise.then(resolve, reject); // 只要有一个Promise完成或拒绝,就将结果传递给resolve或reject
      });
    });
  }
}


常用API



  • then(onFulfilled, onRejected):then方法用于注册回调函数,在Promise状态发生改变时执行相应的回调函数。onFulfilled用于处理Promise状态变为fulfilled时的情况,onRejected用于处理Promise状态变为rejected时的情况。then方法返回一个新的Promise。
  • catch(onRejected):catch方法是then方法的语法糖,只接受onRejected回调函数,用于处理Promise状态变为rejected时的情况。catch方法返回一个新的Promise。
  • Promise.resolve(value):静态方法resolve用于创建一个状态为fulfilled的Promise,并将指定的值传递给resolve。
  • Promise.reject(reason):静态方法reject用于创建一个状态为rejected的Promise,并将指定的原因传递给reject。
  • Promise.all(promises):静态方法all接收一个包含多个Promise的数组,返回一个新的Promise。当所有Promise都变为fulfilled时,新的Promise变为fulfilled,并将每个Promise的值按顺序传递给resolve;如果有任何一个Promise变为rejected,新的Promise将变为rejected,并将第一个被reject的Promise的原因传递给reject。
  • Promise.race(promises):静态方法race接收一个包含多个Promise的数组,返回一个新的Promise。只要有一个Promise变为fulfilled或rejected,新的Promise就会变为相应的状态,并将第一个完成的Promise的结果传递给resolve或reject。


特性



  • 异步操作管理:Promise是用于处理异步操作的一种机制。它可以将异步任务封装为一个Promise对象,使得异步任务的执行和结果可以更加可控和可预测。
  • 状态管理:Promise具有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。初始状态为pending,当异步操作成功完成时状态变为fulfilled,若发生错误则状态变为rejected。状态一旦改变,就不可再变。
  • 链式调用:Promise通过then方法支持链式调用。then方法接收两个参数:onFulfilled(当Promise状态变为fulfilled时调用的回调函数)和onRejected(当Promise状态变为rejected时调用的回调函数)。每次调用then方法后都会返回一个新的Promise对象,因此可以连续调用多个then方法形成链式操作。
  • 值传递:Promise可以将值在异步操作之间传递。当一个Promise状态变为fulfilled时,可以将其值传递给下一个Promise或者通过回调函数返回给调用方。
  • 错误处理:Promise具有错误传递和捕获的能力。在Promise链中,任何一个Promise出现异常都会触发onRejected回调函数,并将异常信息传递到catch方法或后续的错误处理函数中。
  • 多个Promise的协同处理:Promise提供了静态方法如Promise.all和Promise.race,用于处理多个Promise的协同处理情况。Promise.all可以等待多个Promise都成功完成后再执行后续操作,而Promise.race会在第一个完成的Promise上触发后续操作。


适用场景



  • 异步操作:Promise可用于处理异步操作,使代码更易读、维护和扩展。通过then方法链式调用,可以按顺序执行一系列异步操作。
  • AJAX 请求:使用Promise可以更优雅地处理AJAX请求,通过将AJAX封装成Promise,可以在请求成功或失败后执行相应的回调函数。
  • 并发控制:Promise.all方法可以用于并发控制,当多个异步任务都完成时再进行下一步操作。
  • 错误处理:Promise的特性之一是错误捕获和传递。通过catch方法可以统一处理Promise链中的错误,提高代码的可读性和错误管理能力。


后言



创作不易 如果该文章对您有帮助 不妨三联支持一下作者 感谢

下一期会出 promise的链式调用和promise的嵌套的实现

如果感兴趣下次来看


目录
相关文章
|
前端开发 JavaScript 开发者
前端开发中的异步编程:Promise 和 Async/Await 的比较与应用
在现代前端开发中,异步编程是不可或缺的技术。本文将深入探讨Promise和Async/Await这两种主流的异步编程方式,分析它们的优劣势及在实际项目中的应用场景。通过比较它们的语法、可读性和错误处理机制,帮助开发者更好地选择和理解如何在项目中高效地利用这些技术。
|
Ubuntu 数据安全/隐私保护 Docker
|
人工智能 安全 API
claude中文版怎么使用?轻松解锁国内使用Claude 技能
渴望体验 Anthropic 公司开发的强大 AI 模型 Claude 的魅力,却被网络限制所阻挡?不必担心!🚀 这篇指南将为你详细剖析 Claude 的强大功能,并提供多种方法,让你即使身处国内,也能轻松驾驭 Claude 的力量,开启 AI 新世界的大门
|
自然语言处理 开发者
多模态大模型LLM、MLLM性能评估方法
针对多模态大模型(LLM)和多语言大模型(MLLM)的性能评估,本文介绍了多种关键方法和标准,包括模态融合率(MIR)、多模态大语言模型综合评估基准(MME)、CheckList评估方法、多模态增益(MG)和多模态泄露(ML),以及LLaVA Bench。这些方法为评估模型的多模态和多语言能力提供了全面的框架,有助于研究者和开发者优化和改进模型。
1536 5
|
运维 Serverless 数据库
如何使用zipfile模块解压zip文件并返回解压后的结果
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
217 8
|
API 网络架构
【Azure Developer】使用 Microsoft Graph API查看用户状态和登录记录
【Azure Developer】使用 Microsoft Graph API查看用户状态和登录记录
156 0
|
监控 Linux
cento如何查看网口
【6月更文挑战第29天】cento如何查看网口
713 6
|
机器学习/深度学习 缓存 自然语言处理
采用ChatGPT大模型高效精准文档翻译
这款文档翻译工具支持PDF、Word、PPT、Excel和TXT等多种格式,利用ChatGPT大模型进行高效精准的翻译,覆盖30多种语言。它通过文档解析、预处理、翻译和结果合成步骤工作,并采用缓存、并行处理和负载均衡技术优化性能。该工具满足全球化背景下企业和个人的多语言需求,助力信息交流。
814 0
采用ChatGPT大模型高效精准文档翻译
|
NoSQL 物联网 atlas
|
C++
【qt】自定义代理类
【qt】自定义代理类
230 0