JavaScript中的new Promise对象和Promise.all、Promise.race方法(JS中的Promise和Promise.all、Promise.race)

40 篇文章 1 订阅
3 篇文章 0 订阅

简介:JavaScript中的Promise对象是随着ES6(ECMAScript 2015)规范发布的,它是异步编程中的一种解决方案或者规范,解决了回调地狱的问题。它本质上是一个构造函数,可以实例化一个对象,从中获取异步操作的最终状态,使得异步代码可以像同步代码一样进行链式调用,从而提高代码的可读性和可维护性。

一、Promise的状态、方法,以及应用场景

在JavaScript中,Promise是一种强大的工具,用于处理异步操作。它提供了一种统一的接口,使得异步代码可以像同步代码一样进行链式调用,并且具有更好的错误处理机制。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),同时,Promise也提供了两个用于改变状态的方法:resolve和reject,以及.then、.catch、.finally方法。

1. Promise的状态

  • pending(进行中):这是Promise的初始状态,既不是成功也不是失败。
  • fulfilled(已成功):这意味着操作成功完成。一旦Promise进入此状态,就不会再改变。
  • rejected(已失败):这意味着操作失败。与fulfilled状态一样,一旦进入此状态,就不会再改变。

2. 改变Promise状态的方法

  • resolve(value):将Promise的状态从pending变为fulfilled,并将value作为成功的结果。
  • reject(reason):将Promise的状态从pending变为rejected,并将reason作为失败的原因。

3. Promise的方法

  • .then(onFulfilled, onRejected):返回一个新的Promise,当原Promise状态变为fulfilled时,调用onFulfilled函数;当原Promise状态变为rejected时,调用onRejected函数。
  • .catch(onRejected):是.then(null, onRejected)的简写,用于指定一个拒绝状态的回调函数。
  • .finally(onFinally):无论Promise的状态如何,都会执行onFinally函数。  

4. 应用场景与实例

 场景1:Promise的执行顺序

(1)、Promise是一个同步任务也是一个微任务,只有在执行了resolve或者reject后,才会执行.then或者.catch操作,变成微任务

// Promise的执行顺序

let myPromise = new Promise((resolve, reject) => {
  console.log(1);
  console.log(2);
  // resolve();
  // reject();
})
myPromise.then(() => {
  console.log(3);
}).catch(() => {
  console.log(4);
}).finally(() => {
  console.log(5);
})
console.log(6);
//控制台输出1 2 6,不会走.then .catch .finally方法,
//因为没有执行resolve() 或者 reject()方法


let myPromise2 = new Promise((resolve, reject) => {
  console.log(1);
  console.log(2);
  resolve();
  // reject();
})
myPromise.then(() => {
  console.log(3);
}).catch(() => {
  console.log(4);
}).finally(() => {
  console.log(5);
})
console.log(6);
//控制台输出1 2 6 3 5,因为执行了resolve()方法

场景2:异步操作

(2)、假设我们有一个异步函数fetchData(),用于从服务器获取数据,这时使用Promise可以更方便地处理这个异步操作。

// 模拟异步操作  
function fetchData() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      // 模拟成功获取数据  
      resolve('成功获取数据');  
      // 或者模拟失败  
      // reject('获取数据失败');  
    }, 1000);  
  });  
}  
  
// 使用.then处理成功结果,使用.catch处理失败结果  
fetchData()  
  .then(data => {  
    console.log(data); // 输出:成功获取数据  
  })  
  .catch(error => {  
    console.error(error); // 如果reject被调用,则会执行这里  
  });

场景3:错误处理

(3)、Promise允许我们更优雅地处理错误,通过.catch方法,我们可以捕获Promise链中任何地方的错误。

function PromiseError() {  
  return new Promise((resolve, reject) => {  
    reject('发生错误');  
  });  
}  
  
PromiseError()  
  .then(result => {  
    console.log(result);  
  })  
  .catch(error => {  
    console.error('捕获到错误:', error); // 输出:捕获到错误: 发生错误  
  });


场景4:链式调用

(4)、Promise允许我们进行链式调用,这使得代码更加清晰和易于维护。

function promise1() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => resolve('promise1的结果'), 1000);  
  });  
}  
  
function promise2(value) {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => resolve(`promise2的结果:${value}`), 1000);  
  });  
}  
  
promise1()  
  .then(result => {  
    console.log(result); // 输出:promise1的结果  
    return promise2(result);  
  })  
  .then(result => {  
    console.log(result); // 输出:promise2的结果:promise1的结果  
  })  
  .catch(error => {  
    console.error('发生错误:', error);  
  });


场景5:使用.finally进行清理

(5)、无论Promise的状态如何,.finally方法都会执行。这可以用于进行资源清理或执行一些必须的操作。

function myPromise() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => resolve('操作成功'), 1000);  
  });  
}  
  
myPromise()  
  .then(result => {  
    console.log(result); // 输出:操作成功  
  })  
  .catch(error => {  
    console.error('发生错误:', error);  
  })  
  .finally(() => {  
    console.log('无论成功还是失败,都会执行这里。'); // 总是输出这句话
   })

小结:

  1. Promise 有三种状态(pending、fulfilled、rejected)和两个方法(resolve、reject)共同构成了异步操作处理的核心机制;

  2. 通过调用 resolve 和 reject 来改变 Promise 的状态,最后通过 then、catch 、finally等方法来处理这些状态及其结果;

  3. Promise即是一个同步任务也是一个微任务,它会首先执行自身的同步任务,只有在执行了resolve或者reject后,才会执行.then或者.catch操作,变成微任务。

5. Promise在执行了reslove或者reject后,如果后续有.then、.catch、箭头函数时,会直接执行箭头函数。

二. Promise.all方法

1. 方法详细

  • Promise.all是一种用于处理多个Promise对象的方法,该方法接收一个数组作为参数,并返回一个新的Promise对象。这个对象会在所有Promise对象都成功解析后解析,解析的结果是一个数组,包含了所有Promise对象解析后的结果。

  •  解析时如果任何一个Promise对象失败,则这个新的Promise对象会立即失败,并返回第一个失败的Promise对象的错误信息。

  • Promise.all不会改变原有的Promise对象的状态,原有的 Promise 对象仍会按照自己的状态(fulfilled或rejected)进行解析。

2. 使用实例

// 假设有两个异步函数 asyncFetchData1 和 asyncFetchData2,它们分别返回Promise对象  
  
// 异步函数 asyncFetchData1 ,模拟请求数据1  
function asyncFetchData1 () {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      resolve('fetchData1');  
    }, 1000);  
  });  
}  
  
// 异步函数 asyncFetchData2,模拟请求数据2  
function asyncFetchData2() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      resolve('fetchData2');  
    }, 1500);  
  });  
}  
  
// 使用 Promise.all 同时执行两个异步函数  
Promise.all([asyncFetchData1(), asyncFetchData2()])  
  .then((results) => {  
    // 当所有Promise都成功完成时,results是一个包含所有结果的数组  
    console.log(results); // 输出: ['fetchData1', 'fetchData2']  
  })  
  .catch((error) => {  
    // 如果有任何一个Promise失败,这个catch会捕获到错误  
    console.error('An error occurred:', error);  
  });  
  
// 注意:Promise.all 的结果数组中的元素顺序与传入的Promise数组中的顺序一致

三. Promise.race方法

1. 方法详细

Promise.race也是一种用于处理多个 Promise实例的方法,与Promise.all 不同的是,Promise.race 会对比所有的 Promise对象,只要有一个 Promise 对象的状态发生改变,无论是 fulfilled 还是 rejected,Promise.race就返回同样的状态。

2. 使用实例

// 假设有两个异步函数 fetchDataFast 和 fetchDataSlow,它们分别返回 Promise 对象  
  
// 异步函数 fetchDataFast,模拟一个快速完成的 API 请求  
function fetchDataFast() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      resolve('fastData');  
    }, 500); // 假设这个请求很快,只需要 500 毫秒  
  });  
}  
  
// 异步函数 fetchDataSlow,模拟一个慢速完成的 API 请求  
function fetchDataSlow() {  
  return new Promise((resolve, reject) => {  
    setTimeout(() => {  
      resolve('slowData');  
    }, 2000); // 假设这个请求很慢,需要 2000 毫秒  
  });  
}  
  
// 使用 Promise.race 同时执行两个异步函数,但只关心第一个完成的结果(无论成功和失败)  
Promise.race([fetchDataFast(), fetchDataSlow()])  
  .then((data) => {  
    // 这个 .then 会在第一个 Promise 完成时触发  
    console.log('First data received:', data); 
    // 输出接收到的第一个数据:  fastData  
  })  
  .catch((error) => {  
    // 如果有任何一个 Promise 拒绝,这个 .catch 会捕获到错误  
    console.error('An error occurred:', error);  
  });  
  
// 由于 fetchDataFast 比 fetchDataSlow 先完成,因此最终只会输出 fast API 的数据

创作不易,感觉有用,就一键三连,感谢(●'◡'●)

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PromiseJavaScript处理异步操作的一种机制。它是一种代表了异步操作最终完成或失败的对象Promise有三种状态:pending(进行)、fulfilled(已成功)和rejected(已失败)。当一个Promise对象的状态从pending变为fulfilled或rejected时,会触发相应的回调函数。 Promise.all和Promise.racePromise的两个静态方法,用于处理多个Promise对象。 1. Promise.all:接收一个Promise对象的可迭代参数,返回一个新的Promise对象。当所有的Promise对象都变为fulfilled状态时,新的Promise对象才会变为fulfilled状态,并返回一个包含所有Promise结果的数组。如果其一个Promise对象变为rejected状态,新的Promise对象会立即变为rejected状态,并返回第一个被rejected的Promise对象的结果。 2. Promise.race:接收一个Promise对象的可迭代参数,返回一个新的Promise对象。当其一个Promise对象变为fulfilled或rejected状态时,新的Promise对象会立即变为相同的状态,并返回第一个完成的Promise对象的结果。 使用场景: - Promise.all适用于需要等待多个异步操作全部完成后再进行下一步操作的情况,例如同时发送多个请求并等待所有请求完成后再进行数据处理。 - Promise.race适用于需要获取最快完成的异步操作结果的情况,例如多个请求同时发送,只需要获取最先返回的结果。 范例: ```javascript const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 1 resolved'); }, 2000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise 2 resolved'); }, 1000); }); const promise3 = new Promise((resolve, reject) => { setTimeout(() => { reject('Promise 3 rejected'); }, 1500); }); Promise.all([promise1, promise2]) .then(results => { console.log(results); // 输出:['Promise 1 resolved', 'Promise 2 resolved'] }) .catch(error => { console.log(error); }); Promise.race([promise1, promise2, promise3]) .then(result => { console.log(result); // 输出:'Promise 2 resolved' }) .catch(error => { console.log(error); // 输出:'Promise 3 rejected' }); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北城笑笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值