Promise介绍

一、promise基本概念

1.1 回调问题

在平常敲代码中经常会遇到多层回调函数的相互嵌套问题。如下:

这会使得代码耦合性太强,牵一发而动全身,难以维护 。大量冗余的代码相互嵌套,代码的可读性变差。

1.2 如何解决回调问题

为了解决回调过深的问题, ES6 (ECMAScript 2015)中新增了 Promise 的概念。

1.3 Promise 的基本概念

 Promise 是一个构造函数
         我们可以创建 Promise 的实例 const p = new Promise()
         new 出来的 Promise 实例对象, 代表一个异步操作

二、Promise.then()

Promise.prototype 上包含一个 .then() 方法

         每一次 new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到 .then() 方法,例如 p.then()。
then() 方法用来预先指定成功和失败的回调函数

then()方法是异步执行。意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。

 a. p.then(成功的回调函数,失败的回调函数)
 b. p.then(result => { }, error => { })
 c. 调用 .then() 方法时,成功的回调函数是必选的、失败的回调函数是可选的
一个简单的读取文件例子:
thenFs.readFile('./files/1.txt', 'utf8').then((r1) => { console.log(r1) })//111

三、Promise链式调用

 3.1 .then()方法特性

      promise支持链式调用。如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通 过 .then() 方法的链式调用,就解决了回调过深的问题。

就例如想要按顺序读取文件内容:

import thenFs from "then-fs";

thenFs.readFile('./files/1.txt', 'utf8')
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    })

通过链式调用姐简洁的实现了按顺序读取文件1,2,3的内容 。

四、Promise.catch()

通过 .catch 捕获错误
        在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype. catch 方法进行捕获和处理:
thenFs.readFile('./files/11.txt', 'utf8')//(文件路径错误,导致后面3个.then()都无法执行)
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    }).catch((err) => {   // 捕获第一行错误 输出错误内容
        console.log(err.message);
    })

         如果不希望前面的错误导致后续的 .then 无法正常执行,则可以将 .catch 的调用提前,示例代码如下:

thenFs.readFile('./files/11.txt', 'utf8')
    .catch((err) => {   //捕获异常错误   提前捕获  可继续执行
        console.log(err.message);
    })
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    })

五、Promise.all()和Promise.race() 方法

        Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then 操作(等待机制)。

        Promise.race() 方法会发起并行的 Promise 异步操作, 只要任何一个异步操作完成,就立即执行下一步的 .then 操作 (赛跑机制)。

示例代码如下:

import thenFs from "then-fs";

const promiseArr = [
    thenFs.readFile('./files/1.txt', 'utf8'),
    thenFs.readFile('./files/2.txt', 'utf8'),
    thenFs.readFile('./files/3.txt', 'utf8')
]

// Promise.all(promiseArr).then((result) => {   //所有完成才返回
Promise.race(promiseArr).then((result) => {   //有一个完成了就返回
    console.log(result);
})

 

### JavaScript 中的 Promise #### 创建 Promise 对象 在 JavaScript 中,`Promise` 是一种用于处理异步操作的对象。创建 `Promise` 实例时需传入一个执行器函数(executor),此函数接收两个参数:`resolve` 和 `reject` 函数[^3]。 ```javascript let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Operation successful'); }, 2000); }); ``` 这段代码展示了如何通过设置定时器模拟耗时的操作,在两秒后调用 `resolve()` 来表示操作已完成并传递消息给后续链式调用的方法。 #### 处理成功与失败的结果 为了响应由 `Promise` 发起的任务状态变化,通常采用 `.then(onFulfilled, onRejected)` 方法来指定当承诺被兑现或拒绝后的回调逻辑[^1]。 对于上述例子而言: ```javascript promise.then( (value) => console.log(`Success: ${value}`), // 当 Promise 被解决(resolve)时触发 (reason) => console.error(`Error occurred: ${reason}`) // 如果发生异常(reject)则捕获这里 ); ``` 值得注意的是,`.then()` 的第一个参数是针对成功的场景而第二个则是用来捕捉可能发生的错误情况;当然也可以单独定义只关心某一方面的行为。 #### 错误传播机制 除了显式的调用 `reject(reason)` 抛出错误外,还可以利用 `throw` 关键字直接引发异常从而进入下一个最近的 `.catch()` 或者未指明拒绝处理器的 `.then(null, rejectionHandler)` 分支中去[^2]。 下面的例子说明了这一点: ```javascript const myPromise = new Promise((resolve, reject) => { console.log('Creating a promise instance...'); resolve('success message'); }); myPromise .then((value) => { console.log('Value:', value); return new Error('An error has been thrown'); // 这里可以替换为 throw new Error() }) .then((value) => { console.log(value); // 不会被打印因为上一步已经转到 catch 流程 }) .catch((error) => { console.warn('Caught an error:', error.message); }); ``` 在这个案例里面,尽管第一次的成功路径正常工作,但在第二次尝试继续链条的时候由于遇到了错误所以跳过了中间部分直接进入了最后的错误处理环节。 #### 并发执行多个 Promises 有时需要同时启动若干个独立但相互关联的任务,并希望等到全部完成后才采取下一步行动。这时就可以借助于静态方法 `Promise.all(iterable)` ,它接受一组可迭代对象作为输入参数,这些成员应当都是 `Promise` 类型实例。一旦所有内部项都完成了(无论是成功还是失败),整个集合也会随之改变其最终的状态[^4]。 ```javascript // 假设有三个不同的 API 请求或其他形式的异步任务 const taskOne = fetch('/api/data/one').then(response => response.json()); const taskTwo = fetch('/api/data/two').then(response => response.json()); const taskThree = fetch('/api/data/three').then(response => response.json()); // 同时发起这三个请求并将结果汇总在一起 Promise.all([taskOne, taskTwo, taskThree]) .then(([resultOne, resultTwo, resultThree]) => { console.table({ resultOne, resultTwo, resultThree }); }) .catch(error => console.error('At least one of the promises was rejected.', error)); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值