当前位置: 首页 > news >正文

Promise 详细说明、常用方法

Promise 详细说明


上一节:认识 Promise

1. 常用的几种方法

1.1 resolve 方法

resolve 方法作用:将一个普通的值转换成 Promise 类型的数据

方法的状态与结果受参数影响:

  1. 参数非 Promise 对象,将返回一个 Promise 对象,状态为 fulfilled,结果为参数值
  2. 参数为 Promise 对象,将返回的 Promise 对象的状态和参数,与参数相同
let p1 = Promise.resolve(123);
console.log(p1); // Promise {<fulfilled>: 123}

let p2 = Promise.resolve(new Promise((resolve, reject) => { resolve(456); }));
console.log(p2); // Promise {<fulfilled>: 456}

let p3 = Promise.resolve(new Promise((resolve, reject) => { reject("error"); }));
console.log(p3); // Promise {<rejected>: "error"}

1.2 reject 方法

Promise.reject() 方法始终返回一个失败的 Promise 对象,并且不受参数的影响。

let p1 = Promise.reject(123);
console.log(p1); // Promise { <state>: "rejected", <value>: 123 }

let p2 = Promise.reject(
  new Promise((resolve, reject) => { resolve(456); })
);
console.log(p2); // Promise { <state>: "rejected", <value>: 456 }

1.3 catch 方法

Promise.catch() 方法用于捕获 Promise 对象失败的错误。

该方法返回一个新的 Promise 对象,该对象在原 Promise 对象的错误状态被捕获或被处理后,才会发生。

new Promise((resolve, reject) => {
  reject("error");
}).catch((err) => {
  console.log(err);
});

1.4 all 方法

Promise 下的 all 方法作用主要针对于多个 Promise 的异步任务的处理,需要接收一个数组类型的参数。

返回值是一个 Promise 对象,状态是由数组中的每一个 Promise 对象的状态来决定的:

  1. 所有的 Promise 对象状态均为成功的,最终的结果就是成功的 Promise 对象,结果值是由每一个 Promise 的结果值组成的数组
  2. 但凡有一个 Promise 对象的状态为失败,最终的结果就是失败的 Promise 对象,结果值就是失败的这个 Promise 的结果值
let p1 = new Promise((resolve, reject) => resolve("ok"); );
let p2 = new Promise((resolve, reject) => resolve("hello"); );
let p3 = new Promise((resolve, reject) => reject("error"); );

let result = Promise.all([p1, p2, p3]);
console.log(result);

1.5 allSettled 方法

Promise.allSettled() 方法用来确定一组异步操作是否全部结束了

其中包含了 fultilledrejected 两种状态

// 封装一个 ajax 函数
function ajax(url) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.send();
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) resolve(xhr.responseText);
        else reject(xhr.responseText);
      }
    };
  });
}

Promise.allSettled([
  ajax("http://iwenwiki.com/api/blueberrypai/getChengpinInfo.php"),
  ajax("http://iwenwiki.com/api/blueberrypai/getListeningInfo.php"),
])
  .then((value) => {
  // console.log(value);
  // 过滤成功和失败两种情况
  let successList = value.filter((item) => item.status === "fulfilled");
  console.log(successList);

  let errorList = value.filter((item) => item.status === "rejected");
  console.log(errorList);
})
  .catch((error) => {
  console.log(error);
});

1.6 any 方法

Promise.any() 方法,参数为一个 Promise 数组

  • 参数中只要有一个 Promise 对象状态为 fulfilled,则返回结果为成功
  • 只有当全部 Promise 对象的状态均为 rejected,则返回结果为失败。

Promise.any()Promise.race() 方法很像,但是有一点不同,就是 Promise.any() 不会因为某个 Promise 对象变成 rejected 状态而结束,必须等到所有参数 Promise 对象变成 rejected 状态才会结束。

let p1 = new Promise((resolve, reject) => { resolve("ok"); });
let p2 = new Promise((resolve, reject) => { resolve("okk"); });
let p3 = new Promise((resolve, reject) => { reject("error"); });

let result = Promise.any([p1, p2, p3]);
console.log(result);

1.7 race 方法

Promise.race() 方法需要传递一个参数,参数为数组,数组中的内容表示的是 Promise 实例化对象,如果有最先到达的状态,无论是成功还是失败,都将以这个对象的状态和结果为最终结果。

let p1 = new Promise((resolve, reject) => { resolve("ok"); });
let p2 = new Promise((resolve, reject) => { resolve("okk"); });
let p3 = new Promise((resolve, reject) => { reject("error"); });

let result = Promise.race([p2, p1, p3]);
console.log(result); // Promise { <state>: "fulfilled", <value>: okk }

1.8 finally 方法

Promise.finally() 方法是 ES6 中新增的特性,表示无论 Promise 对象变成了 fulfilled 状态或是 rejeced 状态,都会执行指定的回调函数,是不接受参数的。

new Promise((resolve, reject) => {
  // resolve("ok");
  reject("error");
})
  .then((value) => {
  console.log(value);
})
  .catch((error) => {
  console.log(error);
})
  .finally(() => {
  console.log("执行了");
});

2. 终止 Promise 链条

终止 Promise 链条原理:通过返回一个空的 Promise 对象来终止 Promise 链条,因为空的 Promise 对象状态为 pending,所以不会触发 then()catch() 方法中的回调函数,从而避免了 Promise 链条中后续的回调函数执行。

new Promise((resolve, reject) => {
  resolve(1);
}).then((value) => {
  console.log(value); // 1
}).then((value) => {
  // console.log(value); // undefined
  console.log(2222);
}).then((value) => {
  // console.log(value); // undefined
  console.log(3333);
  return new Promise(() => {}); // 通过返回一个空的 Promise 对象来终止 Promise 链条
}).then((value) => {
  // console.log(value); // undefined
  console.log(4444);
}).then((value) => {
  // console.log(value); // undefined
  console.log(5555);
}).catch((error) => {
  console.log(error);
});

3. 几个关键问题

3.1 如何修改 Promise 对象的状态

Promise 对象的状态有三种:pending、fulfilled、rejected。

let p1 = new Promise((resolve, reject)=>{
  // 成功
  // resolve('success');

  // 失败
  // reject('error');

  // 抛出异常
  // throw '出错了';

  // 状态只能修改一次
  resolve('ok')
  reject('error');
});
console.log(p1);

3.2 指定多个回调函数的执行情况

问题:一个 Promise 实例对象指定多个成功 / 失败的回调函数,都会进行执行吗?

答案:一定都会执行,但是前提是 Promise 对象的状态已经被更改为成功 / 失败,一定不能是 pending 状态。

let p1 = new Promise((resolve, reject) => {
  // resolve("ok");
  // reject("error");
  throw "异常";
});

p1.then((value) => { console.log(value); }, (reason) => { console.log(reason); });

p1.then((value) => { console.log(value); }, (reason) => { console.log(reason); });

// ...

3.3 指定回调与改变状态的先后顺序

改变 Promise 状态和指定回调函数的执行,谁先谁后?

都有可能:

  • 若执行器函数中为同步任务,则先修改状态,后指定回调;
  • 若执行器函数中为异步任务,则先指定回调,后修改状态。
let p1 = new Promise((resolve, reject) => {
  // 同步任务
  // resolve("ok");

  // 异步任务
  setTimeout(() => { resolve("ok"); }, 1000);
});

p1.then(
  (value) => { console.log(value); },
  (reason) => { console.log(reason); }
);

3.4 then 方法返回结果

查看上一节 then 方法返回结果

3.5 串联多个任务

Promise.then() 方法的链式操作来举例

new Promise((resolve, reject) => {
  // reject();
  resolve('ok')
}).then((value) => {
  console.log(value);
  console.log(222);
}).then((value) => {
  console.log(value);
}).then(
  (value) => { console.log(value); },
  (reason) => { console.log(reason); }
);

下一节:Promise 进阶

http://www.dtcms.com/a/111623.html

相关文章:

  • 【备考高项】模拟预测题(一)综合知识及答案详解
  • C++_模板初阶
  • transform
  • VirtualBox安装FnOS
  • pat学习笔记
  • JavaScript学习19-事件类型之鼠标事件
  • 【2019】【论文笔记】混合石墨烯等离子体光栅在THz下增强非线——
  • 配置文件、Spring日志
  • Java基础 4.4
  • 论文阅读Diffusion Autoencoders: Toward a Meaningful and Decodable Representation
  • Dagster系列教程:快速掌握数据资产定义
  • 数据库系统概述 | 第二章课后习题答案
  • 计算机系统---CPU
  • 嵌入式系统应用-拓展-相关开发软件说明
  • 常见的微信个人号二次开发功能
  • Unity:平滑输入(Input.GetAxis)
  • 【Cursor】切换主题
  • JS API
  • 【软考中级软件设计师】数据表示:原码、反码、补码、移码、浮点数
  • sward V1.0.8版本发布,全面支持各种附件上传预览
  • 初识数据结构——算法效率的“两面性”:时间与空间复杂度全解析
  • yolov12检测 聚类轨迹运动速度
  • 与总社团联合会合作啦
  • Linux的: /proc/sys/net/ipv6/conf/ 笔记250404
  • 操作系统面经(一)
  • 2025年【陕西省安全员C证】报名考试及陕西省安全员C证找解析
  • Qt QTableView QAbstractTableModel实现复选框+代理实现单元格编辑
  • 进行性核上性麻痹:饮食调理为健康护航
  • SpringBoot项目报错: 缺少 Validation
  • 【NLP 55、投机采样加速推理】