LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【JavaScript】什么是 Promise?有什么用途?

admin
2024年8月9日 21:59 本文热度 841

为什么要使用 Promise?

在探讨 Promise 之前,我们先来看一下为什么需要它的出现。

JavaScript 中有一个重要概念 - 异步 (async),它允许我们在执行耗时任务时,不必等待程序完成,而是继续执行下面的代码,直到任务完成再通知。常用的异步操作有:文件操作、数据库操作、AJAX 以及定时器等。

JavaScript 有两种实现异步的方式:

第一种:回调函数 callback function

在 ES6 promise 出现之前,通常使用回调函数 (callback) 实现异步操作。但使用回调函数 callback 存在一个明显的缺点,当需要执行多个异步操作时,代码会不断往内嵌套,这种情况通常被称为“回调地狱”(callback hell)。

callback(() => {
  console.log("Hello!");
  callback(() => {
    console.log("Hello!");
    callback(() => {
      console.log("Hello!");
      callback(() => {
        console.log("Hello!");
      }, 200);
    }, 200);
  }, 200);
}, 200);

而为了解决这种问题,就出现了第二种方法 - promise。

什么是 Promise?

上一段提到 Promise 出现的原因,这一段我们来看那到底 Promise 是什么。

Promise 照英文上的意思,是约定、承诺,它代表的意涵是这个约定请求会在未来每个时刻返回数据给调用者。在 MDN 文件中,Promise 是用来表示 一个异步操作的最终完成(或失败)及其结果值

怎么使用 Promise

Promise 是一个 构造函数,我们需要通过 new 关键字创建一个 Promise。而 Promise 会接收一个函数作为参数,这个函数又称为 executor,executor 会立即执行。如下方代码,若丢入浏览器开发者工具执行,console 的结果会立刻被打打打印出来。

new Promise((resolve, reject) => {
  console.log("executor 立即执行"); // executor 立即执行
});

而 executor 函数,会再接受另外两个函数参数

  • resolve 实现函数:如下方代码,请求成功的例子,正确的时候会调用 resolve 函数,并返回结果。
  • reject 拒绝函数:如下方代码,请求失败的例子,失败的时候会调用 reject 函数,并返回结果。
function requestData(url{
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url === "explainthis.io") {
        resolve("hello welcome to explainthis");
      } else {
        reject("it is not explainthis");
      }
    }, 3000);
  });
}

// 1. 请求成功
requestData("explainthis.io").then((res) => {
  console.log(res); //hello welcome to explainthis
});

//2. 请求失败
requestData("explainthis.com").catch((e) => console.log(e)); //it is not explainthis

Promise 的状态

一个 Promise 一定会处于以下三种状态的其中一种

  1. pending:初始状态,执行了 executor,但还在等待中。
  2. fulfilled:表示操作完成,执行 resolve 函数。
  3. rejected:表示操作失败,执行 reject 函数。

then 的使用

  1. 多次调用

延续前段谈到的,异步用第一种 callback 做法很容易有 callback hell 的产生,而使用 Promise 的好处则可以避免这种难以阅读的写法。

Promise 可以用一种链式 (chaining) 的方式将这些异步操作串连,如下方代码示例,我们可以通过 then 来将等完成之后的操作串起。

function requestData(url{
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url === "explainthis.io") {
        resolve("hello welcome to explainthis");
      } else {
        reject("it is not explainthis");
      }
    }, 3000);
  });
}

requestData("explainthis.io")
  .then((res) => {
    console.log(res); //hello welcome to explainthis
    return 1;
  })
  .then((res) => {
    console.log(res); // 1
    return 2//hello welcome to explainthis
  })
  .then((res) => {
    console.log(res); // 2
  });
  1. then 方法可以接受两个参数,一个为成功的回调,另一个为失败的回调
function requestData(url{
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url === "explainthis.io") {
        resolve("hello welcome to explainthis");
      } else {
        reject("it is not explainthis");
      }
    }, 0);
  });
}

requestData("explainthis.com").then(
  (res) => {
    console.log(res);
  },
  (reason) => {
    console.log(reason);
  }
);

//it is not explainthis

错误处理

Promise 的一个好处是错误处理,最简单的方式是在加上一个 catch 来捕捉错误,并执行一些错误处理代码。如下方代码,如果请求失败,例如由于网络故障,则 Promise 会被拒绝。在这种情况下,catch 方法将捕获错误,并输出错误讯息。

fetch("https://explainthis.com/data")
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error("oops!", error);
  })
  .finally(() => {
    console.log("close loader");
  });

finally 方法

如果有加上 finally,那 Promise 状态不论是 fulfilled 还是 rejected 都会需要执行 finally 方法。finally 是 Promise 处理流程中一个非常有用的方法,它可以帮助我们在不管 Promise 是否成功的状态下,执行一定必要的操作。

使用场景例如,一进入页面要先从服务器 fetch 数据,等待的同时会显示 loading 的画面,而最后不论是否有拿到数据,我们都需要把 loader 关闭。这时候,关闭 loader 的逻辑,就很适合放在 finally 中。如下方代码:

fetch("https://explainthis.com/data")
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  })
  .finally(() => {
    console.log("close loader");
  });

什么是 async/await?

async/await 是一种基于 Promise 之上的语法糖,比 Promise 的写法更像是同步操作。

首先,我们会使用 async 关键字将函数标记为异步函数,异步函数就是指返回值为 Promise 对象的函数。

在异步函数中我们可以调用其他的异步函数,不过不是使用 then(),而是使用 await 语法,await 会等待 Promise 完成之后直接返回最终的结果。

async function getData({
  const res = await fetch("https://getsomedata");
  const data = await res.json();
  console.log(data);
}

getData();

该文章在 2024/8/11 3:08:56 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved