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()
相关推荐
柯南二号32 分钟前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy729334 分钟前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲1 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
王解1 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
欲游山河十万里1 小时前
(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数
前端·ecmascript·es6
明辉光焱1 小时前
【ES6】ES6中,如何实现桥接模式?
前端·javascript·es6·桥接模式
PyAIGCMaster1 小时前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
baozhengw1 小时前
UniAPP快速入门教程(一)
前端·uni-app
nameofworld1 小时前
前端面试笔试(二)
前端·javascript·面试·学习方法·数组去重
帅比九日2 小时前
【HarmonyOS NEXT】实战——登录页面
前端·学习·华为·harmonyos