首页 > 其他分享 >【Web前端】使用 Promise

【Web前端】使用 Promise

时间:2024-11-15 09:19:17浏览次数:3  
标签:Web console 前端 fetch Promise error 失败 response

Promise是异步编程的核心概念之一。代表一个可能尚未完成的操作,并提供了一种机制来处理该操作最终的成功或失败。具体来说,Promise是由异步函数返回的对象,能够指示该操作当前所处的状态。

当Promise被创建时,它会处于“待定”(Pending)状态,这意味着操作尚未完成。在这个阶段,Promise对象可以通过其提供的方法来注册回调函数,以便在操作最终完成后进行相应的处理。一旦操作完成,Promise的状态会变为“已兑现”(Fulfilled),表示成功;或者变为“已拒绝”(Rejected),表示失败。

除了基本的状态管理,Promise还提供了链式调用的能力,使得开发者可以以更加清晰和可读的方式进行异步操作的组合。例如,可以使用.then()方法处理成功的结果,使用.catch()方法处理错误,甚至可以通过.finally()方法执行一些清理工作,无论操作是成功还是失败。


一、什么是 Promise

Promise 是一个代表异步操作最终完成(或失败)及其结果值的对象。它有三种状态:

  • Pending(待定): 初始状态,既不是成功,也不是失败。
  • Fulfilled(已兑现): 操作成功完成。
  • Rejected(已拒绝): 操作失败。

一旦 Promise 被 fulfilled 或 rejected,它的状态就会被锁定,后续的状态无法再改变。


Promise 的基本构造

Promise是通过 ​​new Promise()​​ 构造函数创建的。这个构造函数接受一个执行器(executor)函数作为参数,该函数接收两个参数:​​resolve​​ 和 ​​reject​​。通过调用 ​​resolve​​ 来标记Promise对象状态为已兑现(fulfilled),而通过调用 ​​reject​​​ 则将其标记为已拒绝(rejected)。

const myPromise = new Promise((resolve, reject) => {
    // 模拟异步操作
    const success = true; // 假设操作成功
    if (success) {
        resolve('操作成功'); // 标记Promise为已兑现
    } else {
        reject('操作失败'); // 标记Promise为已拒绝
    }
});

Promise 的使用

一旦创建了Promise对象,可以利用 ​​then()​​ 方法处理Promise对象状态为已兑现时的返回值,也可以使用 ​​catch()​​​ 方法来处理Promise对象状态为已拒绝时的错误信息。

myPromise
    .then(result => {
        console.log(result); // 打印: 操作成功
    })
    .catch(error => {
        console.error(error); // 打印错误信息
    });

当Promise对象状态为已兑现时,​​then()​​方法会调用传入的回调函数并输出成功的信息;当Promise对象状态为已拒绝时,则会调用​​catch()​​​方法中的回调函数输出错误信息。


二、使用 ​​fetch()​​ API

​fetch()​​ API 是一个现代的网络请求接口,广泛用于发起网络请求并处理响应。它返回一个 Promise,使得异步操作的管理变得更加简单和直观。​​fetch()​​​ 通常用于获取网络资源,如 RESTful API 的数据。

基本的 ​​fetch()​​ 使用

以下是使用 ​​fetch()​​ 发送 GET 请求并处理响应的基本示例:

fetch('https://api.example.com/data')
    .then(response => {
        // 检查响应是否成功
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json(); // 解析 JSON 数据
    })
    .then(data => {
        console.log(data); // 输出返回的数据
    })
    .catch(error => {
        console.error('请求失败:', error); // 捕获并输出错误信息
    });
  • ​fetch()​​ 函数向指定的 URL 发送了 GET 请求。
  • 响应通过 ​​.then()​​ 方法处理。如果响应不正常(例如状态码不是 200-299),则会抛出一个错误。
  • 如果响应成功,使用 ​​response.json()​​ 方法解析 JSON 格式的数据,并在随后的 ​​.then()​​​ 中使用解析后的数据。

发送 POST 请求

除了发送 GET 请求外,​​fetch()​​​ 还可以用来发送 POST 请求。在发送 POST 请求时,可以传递一个包含请求体的配置对象。

fetch('https://api.example.com/data', {
    method: 'POST', // 指定请求方法为 POST
    headers: {
        'Content-Type': 'application/json' // 设置请求头部信息
    },
    body: JSON.stringify({ key: 'value' }) // 转换请求体为 JSON 字符串
})
.then(response => {
    // 检查响应状态
    if (!response.ok) {
        throw new Error('网络响应失败');
    }
    return response.json(); // 解析 JSON 数据
})
.then(data => {
    console.log(data); // 输出返回的数据
})
.catch(error => {
    console.error('请求失败:', error); // 捕获并输出错误信息
});
  • 使用 ​​method: 'POST'​​ 指明请求类型。
  • 设置请求头 ​​Content-Type​​ 为 ​​application/json​​,表明请求体的格式。
  • 使用 ​​body​​​ 属性将请求体转换为 JSON 字符串,以便于服务器理解。

三、链式使用 Promise

Promise 提供了链式调用的能力,这意味着可以在一个 ​​then()​​​ 处理程序中返回另一个 Promise,从而形成异步操作的链式结构。


链式调用

下面示例中,展示了如何使用 Promise 的链式调用来依次请求两个不同的数据资源:

fetch('https://api.example.com/data1')
    .then(response => response.json())
    .then(data1 => {
        console.log('数据1:', data1);
        return fetch('https://api.example.com/data2'); // 返回另一个 Promise
    })
    .then(response => response.json())
    .then(data2 => {
        console.log('数据2:', data2);
    })
    .catch(error => {
        console.error('请求失败:', error);
    });
  • 第一个 ​​fetch()​​ 请求获取第一个数据资源,通过 ​​.then()​​ 解析响应为 JSON 数据。
  • 在第一个 ​​.then()​​ 处理程序中,我们输出第一个数据并返回另一个 ​​fetch()​​ 请求,以发起第二个异步操作。
  • 第二个 ​​fetch()​​ 请求获取第二个数据资源,通过 ​​.then()​​ 解析响应为 JSON 数据。
  • 最后一个 ​​.then()​​​ 处理程序输出第二个数据。

工作原理

当一个 Promise 被 ​​resolve​​ 时,它会传递给下一个 ​​.then()​​ 处理程序。如果在 ​​.then()​​​ 处理程序中返回一个新的 Promise,则当前 Promise 的状态将取决于此新 Promise 的状态。这样就形成了一条链,依次处理多个异步操作。


四、错误捕获

在使用 Promise 进行异步操作时,错误处理是非常重要的一部分。通过在 Promise 链中使用 ​​catch()​​​ 方法,可以捕获整个链中发生的错误,并进行相应的处理。

错误处理

示例中展示了如何在一个 Promise 链中处理错误:

fetch('https://api.example.com/data1')
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data1 => {
        console.log('数据1:', data1);
        return fetch('https://api.example.com/data2');
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data2 => {
        console.log('数据2:', data2);
    })
    .catch(error => {
        console.error('请求失败:', error);
    });
  • 每个 ​​.then()​​ 处理程序都会检查响应是否成功。如果不成功,则抛出一个 Error。
  • ​catch()​​ 方法用于捕获所有发生的错误,包括前面任何一个 Promise 的错误。
  • 如果任何一个 Promise 出现错误,后续的 ​​.then()​​ 处理程序会被跳过,直接执行 ​​catch()​​​ 中的错误处理逻辑。

Promise 链中的任何一个 Promise 的错误都会传递到最近的 ​​catch()​​ 方法中。这样做可以确保整个链中的任何一个步骤出现问题时都能得到正确的处理。​​catch()​​​ 方法也可以用来统一处理整个链中的错误,使代码更加清晰和易于维护。


五、Promise 术语

讨论 Promise 中了解一些重要的术语很有帮助。以下是一些常见的 Promise 术语及其含义:

  • Promise 实例: 通过 ​​new Promise()​​ 创建的对象,代表一个异步操作的最终完成或失败。
  • Executor 函数: Promise 构造函数中传递的函数,定义了异步操作的行为和状态变化。
  • then() 方法: 用于处理 Promise 对象的成功状态(fulfilled)的回调函数,接受一个成功的值作为参数。
  • catch() 方法: 用于处理 Promise 对象的失败状态(rejected)的回调函数,接受一个错误作为参数。
  • finally() 方法: 无论 Promise 的状态如何(成功或失败),都会执行的回调函数。

使用 ​​finally()​

下面的示例展示了如何使用 ​​finally()​​ 方法来进行清理工作,无论 Promise 是成功还是失败,​​finally()​​​ 中的回调都会被执行:

fetch('https://api.example.com/data')
    .then(response => {
        if (!response.ok) {
            throw new Error('网络响应失败');
        }
        return response.json();
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error('请求失败:', error);
    })
    .finally(() => {
        console.log('请求完成,无论成功或失败。');
    });
  • 如果获取数据成功,数据将会被输出到控制台。
  • 如果获取数据失败,错误信息将会被输出到控制台。
  • 无论前面的 Promise 是成功还是失败,​​finally()​​​ 中的回调都会被执行,用来进行一些清理工作或其他必要的操作。

六、合并多个 Promise

处理多个异步操作时,可以使用 Promise.all() 和 Promise.race() 这两种方法来组合多个 Promise 对象。

Promise.all()

Promise.all() 方法接收一个包含多个 Promise 的数组作为参数,只有当所有 Promise 都成功时,返回的 Promise 才会成功。如果其中任何一个 Promise 失败,则返回的 Promise 也会失败。

const promise1 = fetch('https://api.example.com/data1');
const promise2 = fetch('https://api.example.com/data2');

Promise.all([promise1, promise2])
    .then(responses => {
        return Promise.all(responses.map(response => {
            if (!response.ok) {
                throw new Error('网络响应失败');
            }
            return response.json();
        }));
    })
    .then(data => {
        console.log('数据:', data);
    })
    .catch(error => {
        console.error('请求失败:', error);
    });
  • 通过 Promise.all() 组合了两个获取数据的 Promise。
  • 如果所有 Promise 都成功,我们会将获取的数据输出到控制台。
  • 如果任何一个 Promise 失败(例如网络响应失败),则捕获并输出错误信息。

Promise.race()

Promise.race() 方法返回一个 Promise,该 Promise 只会在第一个 Promise 解决或拒绝时解决。即使其他 Promise 还没有完成,只要有一个 Promise 在之前完成或失败,race() 返回的 Promise 就会立即解决。

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 100, '第一个 Promise 完成');
});
const promise2 = new Promise((resolve, reject) => {
    setTimeout(reject, 50, '第二个 Promise 失败');
});

Promise.race([promise1, promise2])
    .then(result => {
        console.log(result); // 不会执行,因为 promise2 先失败
    })
    .catch(error => {
        console.error(error); // 输出: 第二个 Promise 失败
    });
  • 创建了两个延迟的 Promise,一个成功一个失败。
  • 使用 Promise.race() 来比较这两个 Promise,结果是第二个 Promise 失败,因此 catch() 方法被触发,输出失败的原因。

7. async 和 await

async 和 await 是 ES2017 引入,用于更简洁地处理 Promise。async 关键字用于定义异步函数,await 用于等待 Promise 解决。

使用 async 和 await

async function fetchData() {
    try {
        const response1 = await fetch('https://api.example.com/data1');
        if (!response1.ok) {
            throw new Error('网络响应失败');
        }
        const data1 = await response1.json();
        console.log('数据1:', data1);

        const response2 = await fetch('https://api.example.com/data2');
        if (!response2.ok) {
            throw new Error('网络响应失败');
        }
        const data2 = await response2.json();
        console.log('数据2:', data2);
    } catch (error) {
        console.error('请求失败:', error);
    }
}

fetchData();
  • 使用 async 定义了一个异步函数 fetchData(),里面包含多个 await 表达式来等待 Promise 解决,并处理返回的数据。
  • 如果任何一个 Promise 解决失败,错误信息将被捕获并输出到控制台。

async 函数的返回值

async 函数总是返回一个 Promise,即使函数内没有显式返回值。下面的示例展示了这一点:

async function example() {
    return 'Hello, World!';
}

example().then(message => {
    console.log(message); // 输出: Hello, World!
});
  • async 函数 example() 返回一个字符串 'Hello, World!'。
  • 虽然在函数内没有显式返回 Promise,但由于是 async 函数,最终返回的仍然是一个 Promise 对象。

标签:Web,console,前端,fetch,Promise,error,失败,response
From: https://blog.csdn.net/LEECOO666/article/details/143785946

相关文章

  • Web前端之汉字排序、sort与localeCompare的介绍、编码顺序与字典顺序的区别
    MENU使用字典顺序对汉字进行排序(不支持多音字)编码顺序和字典顺序的区别sort与localeCompare的介绍使用字典顺序对汉字进行排序(不支持多音字)不使用拼音库,利用JavaScript的localeCompare方法直接按汉字的字典序排序。localeCompare可以在比较字符串时指定语言及排......
  • 【linux日志】web日志分析
    WEB正确日志格式分析#日志统计举例[root@master~]#cat/etc/httpd/logs/access_log|awk'{print$1}'#对IP排序[root@master~]#cat/etc/httpd/logs/access_log|awk'{print$1}'|sort#打印每一个重复出现IP的次数,[root@master~]#cat/etc/httpd/logs/access_......
  • 前端工程工具链
    为了提高整体开发效率,首先要将一些代码规范考虑在内,需要保持git仓库的代码就像是一个人写出来的。根据团队习惯,考虑后使用组合工具:eslint + stylelint + prettier + husky。eslint:对js做规则约束。强制校验stylelint:对css做规则约束prettier:代码格式化。强制格式......
  • [原创]手把手教学之前端0基础到就业——day11( Javascript )
    文章目录day11(Javascript)01Javascript①Javascript是什么②JavaScript组成③Javascript的书写位置1.行内式(不推荐)2.内部位置使用(内嵌式)3.外部位置使用(外链式)02变量1.什么是变量2.定义变量及赋值3.注意事项4.命名规范03输入和输出1)输出形式1......
  • 响应式Web设计:纯HTML和CSS实现技巧
    响应式Web设计是一种确保网页在不同设备和屏幕尺寸下都能良好显示的设计方法。以下是使用纯HTML和CSS实现响应式设计的关键技巧:流式布局(FluidLayouts):使用相对单位(如百分比)而非固定单位(如像素)来定义元素的宽度,使元素能根据容器宽度动态调整。媒体查询(MediaQueries):根据不同......
  • 前端技术中对表格元素的学习
    表格元素目录表格元素rowspan(行合并)colspan(列合并)注意事项在HTML中,<table>表格元素允许你通过特定的属性来合并单元格。这通常用于创建更复杂的表格布局,比如跨越多行或多列的标题或数据。合并单元格可以通过rowspan和colspan属性来实现。rowspan(行合并)rowspan属性用于合并垂......
  • <Project-23 Navigator Portal> Python flask web 网站导航应用 可编辑界面:添加图片、UR
    目的:浏览器的地址簿太厚,如下图:开始,想给每个Web应用加icon来提高辨识度,发现很麻烦:createimage,resize,还要挑来挑去,重复性地添加代码。再看着这些密密麻麻的含有重复与有规则的字符,真刺眼!做这个PortalWeb应用来进行网站应用导航,docker部署后,占用端口:9999,可以在ap......
  • 何为RESTful Web API?
    REST(RepresentationalState Transfer)是一种用于构建网络应用程序的架构风格,特别适用于WebAPI。RESTfulWebAPI是基于REST 原则设计的API,允许客户端与服务器之间进行交互。以下是 REST WebAPI的一些关键概念和特点:1.资源(Resources)在REST 中,所有的内容都被视为资......
  • 网页web无插件播放器EasyPlayer.js播放器firefox和chrome等浏览器报ws地址连接不上
    EasyPlayer.jsH5播放器,是一款能够同时支持HTTP、HTTP-FLV、HLS(m3u8)、WS、WEBRTC、FMP4视频直播与视频点播等多种协议,支持H.264、H.265、AAC、G711A、Mp3等多种音视频编码格式,支持MSE、WASM、WebCodec等多种解码方式,支持Windows、Linux、Android、iOS全平台终端的H5播放器,使用简单......
  • 利用 React 构建现代化 Web 应用的核心实践
    ......