js promise的基本用法和一些API

本文介绍了Promise作为异步编程解决方案的基本用法和API。包括Promise的三种状态:pending、resolved和rejected,以及如何通过then、catch、resolve、reject、all和race方法进行异步控制。通过示例详细解析了Promise链式调用和异步执行顺序,特别是Promise.all和Promise.race的用法及区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MDN上面对promise的解释:
Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象
我的理解就是:Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大。

基本写法
let pro = new Promise((res, rej) => {
    res(1);
    rej(2);
});

pro.then(
        data => console.log(data),
        err => console.log(err)
    );

在ES6中,将一件可以发生异步操作的事件,分为两个阶段unsettled未决阶段和settled已决阶段
在上述代码中,通过new 生成promise对象的时候的promise函数内为未决阶段,在通过then方法处理异步操作的时候为已决阶段。
ES6也将程序分为三种状态pendding resolved rejected
pendding状态处于unsettled未决阶段,resolved rejected状态都处于settled已决阶段。
上述代码中通过new 生成promise对象的时候的promise函数内为padding状态,函数内res把程序推向resolved状态,函数内rej把程序推向rejected状态。
在promise中,一次只能把程序推向一种状态,也就是res或者rej只能执行一个,上述代码用于演示所以同时写了两个。
pro.then方法用于接收promise内推出的状态,参数为两个函数,第一个函数接收res推出的resolved状态,第二个参数接收rej推出的rejected状态。
promise内抛出错误也会把padding状态推向rejected状态。
unsettled阶段,所有的代码都是同步执行,当处于settled阶段就是异步了。也就是res或者rej推向的结果会异步执行
多种情况下展示promise的异步操作

setTimeout(function(){
      console.log(3);
  },0)

  let pro = new Promise((res, rej) => {

      res(1);

      console.log(2);

  });

  pro.then(
          data => console.log(data),
          err => console.log(err)
      );

  console.log(4);

结果会一次输出2 4 1 3。
定时器是异步操作,所以不会一开始就输出。在生成promise的函数内也就是处于unsettled未决阶段是同步操作。但是res是异步操作,所以最先输出 2 。接着由于res是异步操作所以继续往下执行碰到输出4。然后剩下两个异步操作,在js中异步操作会被放入队列中等待执行,队列又分为微队列和宏队列,微队列先于宏队列里的事件加入执行栈。定时器是方法宏队列中,promise的处理是放在微队列中,所以先输出1,在输出3。最终就是 2 4 1 3。

then

promsie中的then方法可以是链式调用。链式链式调用时,如果前一个promise返回的是一个promise,则下一个返回的promise状态和后续处理返回的promise状态一致。

let pro1 = new Promise((res, rej) => {
    res(1);
});

let pro2 = new Promise((res, rej) => {
    rej(2);
});

let pro3 = pro1.then(data => pro1, err => pro2); // pro3.then 输出1
// let pro3 = pro2.then(data => pro1, err => pro2); // pro3.then 输出2

pro3.then(
    data => console.log(data),
    err => console.log(err)
);
promise中的API
catch

catch等同于then方法,但是只接收rej传入的rejected状态。

let pro1 = new Promise((res, rej) => {
    res(1);
})

let pro2 = new Promise((res, rej) => {
    rej(2);
});

pro1.catch(err => console.log(err)); // 报错 Uncaught (in promise) 2
pro2.catch(err => console.log(err)); // 2
resolve()

直接把promise推向resolved状态

let pro1 = new Promise((res, rej) => {
    res(1);
});
// resolve简写
let pro1 = Promise.resolve(1);
reject()

直接把promise推向rejected状态

let pro1 = new Promise((res, rej) => {
    rej(1);
});
// 等同于
let pro1 = Promise.reject(1);
all(arr)

这个方法返回一个新的promise,传入一个promise数组,所有的promise对象都推向resolve就推向成功,一旦有一个失败该promise对象推向失败。

// 模拟
let arr = [];
for(let i = 0; i < 10; i++){ // 模拟成功失败随机
    arr.push(new Promise((res, rej) => {
        if(Math.random() > 0.8){
            res(1);
        } else {
            rej(Math.floor(Math.random() * 10));
        }
    }));
}
// for(let i = 0; i < 10; i++){ // 模拟全部成功
//     arr.push(Promise.resolve(1));
// }
console.log(arr);

let pro = Promise.all(arr);
pro.then(data => {console.log(data)});
pro.catch(err => {console.log(err)});

总结:如果全部成功,则输出每一个promise的resolve结果,如果有一个失败,则直接输出第一个失败的结果。

rach(arr)

当数组中任意一个promise对象完成时,就马上会去使用完成了的promise对象的结果,不管这个结果是成功还是失败

let arr = [];
let pro1 = new Promise((res, rej) => {
    setTimeout(() => {
        res("pro1");
    }, 1000);
});
let pro2 = new Promise((res, rej) => {
    setTimeout(() => {
        rej("pro2");
    }, 500);
});
arr.push(pro1, pro2);
console.log(arr);

let pro = Promise.race(arr);
pro.then(data => {console.log(data)});
pro.catch(err => {console.log(err)});

总结:输出pro2, pro2推向已决状态用时少,所以先执行pro2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值