promise

是什么

Promise 是 JavaScript 中用于处理异步操作的一种对象。它代表了一个尚未完成但承诺会在未来某个时候完成的操作,并允许你在操作完成前注册回调函数。

  • 三种状态

    • Pending 等待
    • Fulfilled 完成
    • Rejected 失败
  • 两个过程

    状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,且一但发生改变便不可二次修改

  • 三个方法

    then:注册fulfilled状态回调函数

    catch:注册rejected状态回调函数

    finally:注册无论成功或失败都会执行的回调函数

属于微任务 是异步任务的一种

Promise.prototype 原型上的方法

Promise.prototype.then

  • .then()方法用于指定当Promise对象的状态变为fulfilled时要执行的回调函数。

  • 它接受两个可选的回调函数作为参数:第一个用于处理成功的情况,第二个(可选的)用于处理错误(但通常不会在这里处理错误,而是使用.catch())。

* 该方法返回结果是一个新的Promise实例,可以继续调用then方法

Promise.prototype.catch

  • .catch()方法用于指定当Promise对象的状态变为rejected(即异步操作失败)时要执行的回调函数。
  • 它只接受一个回调函数作为参数,该回调函数会接收被reject方法传递的错误信息。
javascript 复制代码
getJSON('/posts.json')
.then(function(posts) {
  // ...
})
.catch(function(error) {
  // 处理 getJSON 和 前一个回调函数运行时发生的错误
  console.log('发生错误!', error);
});

上面代码中,getJSON()方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then()方法指定的回调函数;

如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。

另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

Promise.prototype.finally()

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

Promise 类上方法

处理多个异步操作

Promise.all()

Promise.all()接收promise对象数组,返回一个新的promise对象,当数组中所有promise都解决时成功时,返回的promise对象才会解决

javascript 复制代码
const p = Promise.all([p1, p2, p3]);
  • 上面代码中,Promise.all()方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

p的状态由p1p2p3决定,分成两种情况。

  1. 只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

  2. 只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.allSettled()

接收一个 promise 对象数组,并返回一个新的 promise。无论数组中的 promise 是解决还是拒绝,返回的 promise 都会解决

有时候,我们希望等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。

例如获取多个用户的信息,当有几个用户信息成功获取到进行处理

Promise.all()方法只适合所有异步操作都成功的情况,如果有一个操作失败,就无法满足要求。

javascript 复制代码
// Promise.all 示例
const promise1 = Promise.resolve(3);
const promise2 = Promise.resolve(42);
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(values => {
  console.log(values); // [3, 42, "foo"]
}).catch(error => {
  console.error('Error:', error);
});

Promise.all 更适用于处理所有 promise 都需要成功的情况,

而 Promise.allSettled 更适用于需要知道每个 promise 结果的情况。

javascript 复制代码
const promise4 = Promise.resolve(3);
const promise5 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'error');
});
const promise6 = Promise.resolve(42);

Promise.allSettled([promise4, promise5, promise6]).then(results => {
  results.forEach(result => console.log(result.status));
  // fulfilled
  // rejected
  // fulfilled
});
Promise.race()

Promise.race()接收promise对象数组,返回一个新的promise对象,当数组中有一个promise解决时无论成功还是失败,返回的promise对象就会解决

javascript 复制代码
const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理。

Promise.any()

接收promise数组,返回一个新的 Promise

javascript 复制代码
Promise.any([
  fetch('https://v8.dev/').then(() => 'home'),
  fetch('https://v8.dev/blog').then(() => 'blog'),
  fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => {  // 只要有一个 fetch() 请求成功
  console.log(first);
}).catch((error) => { // 所有三个 fetch() 全部请求失败
  console.log(error);
});
  • 只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;
  • 如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

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

创建promise对象

Promise.resolve()

Promise.resolve() 方法一般情况下返回一个状态为已解决的 Promise 对象。

参数可以是:

  1. 一个 Promise 对象:直接返回该 Promise 对象。
  2. 一个 thenable 对象 (即具有 then 方法的对象):将其视为 Promise 对象并返回一个新的 Promise,该 Promise 会采用该 thenable 对象的最终状态。
  3. 非 Promise/thenable 值:返回一个新的已解决的 Promise 对象,其解决值为该参数值。
Promise.reject()

Promise.reject() 方法返回一个状态为已拒绝的 Promise 对象。

参数是拒绝理由,可以是任何类型的值(通常是一个 Error 对象或字符串)。

为什么

  • 在js中实现异步操作
  • 可以链式调用,解决回调地狱的问题

回调地狱

js 复制代码
fs.readFile('file1.txt', function(err, data1) {
  if (err) throw err;
  fs.readFile('file2.txt', function(err, data2) {
    if (err) throw err;
    fs.readFile('file3.txt', function(err, data3) {
      if (err) throw err;
      // 继续嵌套下去...
    });
  });
});

Promise 的链式调用可以让我们避免回调地狱。每个 .then 方法都会返回一个新的 Promise,因此可以使用链式调用处理多个异步操作

怎么办

创建promise对象

  1. new Promise(excutor(resolve,reject))
  • 初始化,接收执行器函数作为参数,
  • 执行器函数的参数是两个函数(js内置),用来改变promise的状态

执行器函数是同步执行的

  1. Promise.resolve()/reject()
  • 一般情况下返回的是状态已经改变的promise

代码

基础用法

js 复制代码
//1.基本用法

let promise = new Promise((resolve,reject)=>{

    //异步操作

    setTimeout(()=>{

        let success=false;//异步操作的结果

        if(success)

        {

            resolve('操作成功')//操作成功,传递结果

        }else{

            reject('操作失败')//操作失败,传递原因

        }

    },1000)

})

  

promise.then(res=>{

    console.log(res);//操作成功时处理

}).catch(err=>{

    console.log(err);//操作失败时处理

})

链式调用

js 复制代码
//链式调用

new Promise((resolve,reject)=>{

    setTimeout(()=>{

        resolve(1)

    },1000)

}).then((res)=>{

    console.log(res); //1

    return res*2;

}).then((res)=>{

    console.log(res); //2

    return res*2;

}).then((res)=>{

    console.log(res); //4

}).catch(err=>{

    console.log(err);

})

多个promise的并发处理

js 复制代码
//3.多个promise并发处理

let promise1 = new Promise(resolve => setTimeout(() => resolve('Promise 1 完成'), 1000));

let promise2 = new Promise(resolve => setTimeout(() => resolve('Promise 2 完成'), 2000));

  

// Promise.all([promise1,promise2]).then((ress)=>{

//     console.log(ress);//[ 'Promise 1 完成', 'Promise 2 完成' ]

// }).catch(err=>{

//     console.log(err);

// })

  

// 使用 Promise.race 只等待第一个完成的 Promise

Promise.race([promise1, promise2]).then(result => {

    console.log(result); // "Promise 1 完成"

}).catch(error => {

    console.error(error);

});

与async/await结合使用

  • async 声明一个函数是异步的
  • await 暂停异步函数的执行,等待Promise解决后再继续执行。
js 复制代码
//4. 与 async/await 结合使用

let promise1 = new Promise(resolve => setTimeout(() => resolve('Promise 1 完成'), 1000));

let promise2 = new Promise(resolve => setTimeout(() => resolve('Promise 2 完成'), 2000));

async function myPromise() {

     try{

        let result1 = await promise1; // 等待 promise1 完成

        console.log(result1);

        let result2 = await promise2; // 等待 promise2 完成

        console.log(result2);

     }catch (err){

        console.log(err);

     }

}

  

myPromise()
相关推荐
拉不动的猪1 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程18 分钟前
ES练习册
java·前端·elasticsearch
Asthenia041225 分钟前
Netty编解码器详解与实战
前端
袁煦丞30 分钟前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛1 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员2 小时前
layui时间范围
前端·javascript·layui
NoneCoder2 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19702 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端
烛阴2 小时前
面试必考!一招教你区分JavaScript静态函数和普通函数,快收藏!
前端·javascript