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

Promise 基础:异步编程的救星

在 JavaScript 开发中,异步编程是一个常见的需求,尤其是在处理网络请求、文件操作或定时任务时。然而,传统的回调函数方式很容易导致代码嵌套过深,形成“回调地狱”,使得代码难以阅读和维护。为了解决这一问题,Promise A+ 规范应运而生,并在 ES6 中得到了实现。

一、什么是 Promise

Promise 是一种用于处理异步操作的对象,它代表了一个可能还未完成的操作。Promise 有三个状态:

  1. Pending(挂起):初始状态,既不是成功,也不是失败。
  2. Fulfilled(完成):操作成功完成。
  3. Rejected(失败):操作失败。

Promise 的状态转换是单向的,一旦从 Pending 转变为 Fulfilled 或 Rejected,状态就固定下来,无法再改变。

const pro1 = new Promise((resolve, reject) => {console.log('任务开始');resolve(1);reject(2); // 无效resolve(3); // 无效console.log('任务结束');
});console.log(pro1);pro1.then((data) => {console.log(data); // 1},(reason) => {console.log(reason);}
);

在这个例子中,resolve(1) 将 Promise 的状态从 Pending 转变为 Fulfilled,并传递了值 1。后续的 reject(2)resolve(3) 都是无效的,因为 Promise 的状态已经固定为 Fulfilled。

二、创建 Promise

Promise 的构造函数接受一个执行器函数,该函数会立即被调用,并且可以调用 resolvereject 来改变 Promise 的状态。以下是一个简单的例子:

const pro = new Promise((resolve, reject) => {// 模拟异步操作setTimeout(() => {const success = true; // 假设这是异步操作的结果if (success) {resolve('操作成功');} else {reject('操作失败');}}, 1000);
});pro.then((data) => {console.log(data); // 操作成功},(reason) => {console.log(reason); // 操作失败}
);

在这个例子中,我们创建了一个 Promise 对象 pro,并在 1 秒后通过 resolvereject 改变了它的状态。then 方法用于指定任务完成或失败后的处理函数。

三、Promise 的实际应用

1. 延迟操作

假设我们需要一个函数来延迟一段指定的时间,然后执行某个操作。使用 Promise 可以轻松实现:

function delay(duration) {return new Promise((resolve) => {setTimeout(() => {resolve();}, duration);});
}delay(1000).then(() => {console.log('finish');
});

在这个例子中,delay 函数返回一个 Promise 对象,该对象在指定的时间后通过 resolve 完成。

2. 加载图片

加载图片是一个常见的异步操作,我们可以使用 Promise 来处理图片的加载成功或失败:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div class="container"></div><p class="label"></p><script>function createImage(imgUrl) {return new Promise((resolve, reject) => {const img = document.createElement('img');img.src = imgUrl;img.onload = () => {resolve(img);};img.onerror = (e) => {reject(e);};});}const url1 = 'myImage.jpg';createImage(url1).then((img) => {const p = document.querySelector('.label');p.innerHTML = `${img.width} * ${img.height}`;const div = document.querySelector('.container');div.appendChild(img);},(reason) => {console.log(reason);});</script>
</body>
</html>

在这个例子中,createImage 函数返回一个 Promise 对象,该对象在图片加载成功时通过 resolve 完成,并返回图片 DOM 元素;在图片加载失败时通过 reject 失败,并返回错误原因。

3. 加载远程数据

假设我们需要从远程服务器加载数据,可以使用 Promise 来处理:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><select id="selProvince"></select><script>function getProvinces() {return fetch('https://study.duyiedu.com/api/citylist').then((resp) => resp.json()).then((resp) => resp.data).then((resp) =>resp.map((it) => ({ value: it.value, label: it.label })));}getProvinces().then((ps) => {const html = ps.map((p) => `<option value="${p.value}">${p.label}</option>`).join('');const selProvince = document.getElementById('selProvince');selProvince.innerHTML = html;},(reason) => {console.log(reason);});</script>
</body>
</html>

在这个例子中,getProvinces 函数返回一个 Promise 对象,该对象在成功加载数据时通过 resolve 完成,并返回省份数组;在加载失败时通过 reject 失败,并返回错误原因。

总结

Promise 是一种强大的工具,用于处理异步操作。它通过标准化的接口,使得异步代码更加清晰、简洁、统一。通过本文的介绍,希望你能够更好地理解和使用 Promise,从而在实际开发中避免回调地狱的困扰。

http://www.xdnf.cn/news/13055.html

相关文章:

  • 使用idea开发工具创建javaweb项目工程
  • CQF预备知识:Python相关库 -- 傅里叶变换 scipy.fft
  • 第十八章 归档与备份
  • python打卡第48天
  • linux库(AI回答)
  • SpringBoot的5种日志输出规范策略
  • 深入理解 x86 汇编中的符号扩展指令:从 CBW 到 CDQ 的全解析
  • 《光子技术成像技术》第三章 预习2025.6.8
  • 代码审计 BlueCms SQL注入
  • Linux 文件系统底层原理笔记:磁盘结构、ext2 文件系统与软硬链接解析
  • 基于Python学习《Head First设计模式》第九章 迭代器和组合模式
  • Spring Cloud 微服务架构实战指南 -- SpringCLoud概述
  • [深度学习]搭建开发平台及Tensor基础
  • 第23讲、Odoo18 二开常见陷阱
  • SQL导出Excel支持正则脱敏
  • AtCoder AT_abc409_c [ABC409C] Equilateral Triangle
  • Agent短期记忆的几种持久化存储方式
  • 时间序列预测的机器学习方法:从基础到实战
  • HTML前端开发:JavaScript 获取元素方法详解
  • 5. TypeScript 类型缩小
  • 【JVM】Java虚拟机(三)——类加载与类加载器
  • synchronized 关键字​​ 和 ​​Lock 接口(ReentrantLock)​​ 的详细说明及示例,涵盖核心概念、使用场景、代码实现及两者对比
  • 【Elasticsearch】映射:fielddata 详解
  • 【C++特殊工具与技术】优化内存分配(三):operator new函数和opertor delete函数
  • Linux多线程---线程池实现
  • STM32CubeMX-H7-20-ESP8266通信(下)-双单片机各控制一个ESP8266实现通信
  • LLMs 系列科普文(13)
  • 【Java实战】反射操作百倍性能优化
  • MyBatis原理剖析(一)
  • 人工智能学习08-类与对象