Promise总结

Promise

只有promise调用then的时候,then里面的函数才会被推入微任务中;

1.Promise的三个状态

pending(进行中)、fulfilled(已成功)、rejected(已失败)

  • 只有异步操作的结果可以改变状态,其他任何操作都无法改变,即承诺

状态改变只有2种可能

  • 1.1 pending->fulfilled
  • 1.2 pending->rejected

状态改变就不会再变,如果改变已经发生,再对Promise对象添加回调函数也会立即得到结果

这与事件(Event)完全不同,即错过了它再去监听,是得不到结果的。

如果某些事件不断地反复发生,一般来说,使用 Stream 模式是比部署Promise更好的选择。

2.基本用法

Promise构造函数接收一个函数作为参数,该函数的两个参数分别为resolve和rejecte,也是函数。

  • resolve函数的作用:将Promise对象的状态从“未完成”变为“成功”,并将异步操作的结果作为参数传递出去;
  • rejecte函数的作用:将Promise对象的状态从“未完成”变为“失败”,将错误作为参数传递出去。

Promise实例生成以后,用then方法分别制定resolved状态和rejected状态的回调函数。

⬆️它们都接受Promise对象传出的值作为参数

3.Promise.prototype.then()

then方法返回一个新的Promise实例

前一个实例返回的参数可能还是一个Promise对象(即有异步操作),这时后一个回调函数会等待该Promise对象的状态发生变化才会被调用。

4.Promise.prototype.catch()

状态变为rejected时执行,另外then方法指定的回调函数如果运行中抛出错误也会被捕获

如果Promise的状态已经变为resolved了,再抛出错误是无效的。

和传统的try/catch不同,如果没有catch()指定错误处理,Promise对象抛出的错误不会传递到外部代码。不会有任何反应。

  • catch方法返回的还是一个Promise对象,后面可以继续跟then()或者catch(),后面的then报错和前面的catch无关了。

5.Promise.prototype.finally()

不管如何,都会执行的代码,即then的特例,不管状态如何都会执行

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

6.Promise.all()

用于将多个 Promise 实例,包装成一个新的 Promise 实例

  • 对于Promise.all([p1,p2,p3]),只有p1、p2、p3的状态都为fulfilled,p的状态才会为fulfilled

7.Promise.race()

参数与Promise.all()一样,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝

8.Promise.allSettled()

只有等所有参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束

9.Promise.resolve()

有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。


Promise中一些需要注意的地方

对于推迟

begin->1->2->3->then->4 可以发现then推迟了两个时序
// 推迟原因:浏览器会创建一个 PromiseResolveThenableJob 去处理这个 Promise 实例,这是一个微任务。
// 等到下次循环到来这个微任务会执行,也就是PromiseResolveThenableJob 执行中的时候,因为这个Promise 实例是fulfilled状态,所以又会注册一个它的.then()回调
// 又等一次循环到这个Promise 实例它的.then()回调执行后,才会注册下面的这个.then(),于是就被推迟了两个时序

then方法里面参数若不是函数,会发生值透传

onResolved = typeof onResolved === 'function' ? onResolved : value => value
var promise  = new Promise((resolve, reject) => {
	console.log(1)
})
// 没有reslove,then里面函数不会执行,但此处参数不是函数,发生值透出传,即value => value,判断是否为函数时顺便执行了log
promise.then( console.log(2) )
console.log(3)
// 1
// 2
// 3
Promise.resolve(1)
	.then(2) // 非函数,值透传
	.then(Promise.resolve(3)) // 非函数,值透传
	.then(console.log)
// 1

Promises实现异步调度

/**
 * 题目:JS 实现异步调度器
 * 要求:
 *  JS 实现一个带并发限制的异步调度器 Scheduler,保证同时运行的任务最多有 2 个
 *  完善下面代码中的 Scheduler 类,使程序能正确输出
 */

class Scheduler {
  add(promiseCreator) {
    // ...
  }
  // ...
}

const timeout = (time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, time);
  });
};
const scheduler = new Scheduler();
const addTack = (time, order) => {
  return scheduler
    .add(() => timeout(time))
    .then(() => console.log(order));
};
addTack(1000, '1');
addTack(500, '2');
addTack(300, '3');
addTack(400, '4');

// 输出:2 3 1 4
// 一开始,1、2 两个任务进入队列
// 500ms 时,完成 2,输出 2,任务 3 进队
// 800ms 时,完成 3,输出 3,任务 4 进队
// 1000ms 时,完成 1,输出 1,没有下一个进队的
// 1200ms 时,完成 4,输出 4,没有下一个进队的
// 进队完成,输出 2 3 1 4
class Scheduler {
  constructor(maxLen) {
    this.maxLen = maxLen
    this.taskList = []
    this.count = 0
  }

  async add(promiseCreator) {
    // ...
    if (this.count >= this.maxLen) {
      await new Promise((resolve) => {
        this.taskList.push(resolve)
      })
    }

    this.count++

    let result = await promiseCreator()

    this.count--

    if (this.taskList.length) {
      // 即执行resolve改变状态,解除阻塞,执行await后面的方法
      this.taskList.shift()()
    }

    return result

  }
  // ...
}


const timeout = (time) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, time);
  });
};
const scheduler = new Scheduler(2);
const addTack = (time, order) => {
  return scheduler
    .add(() => timeout(time))
    .then(() => console.log(order));
};
addTack(1000, '1');
addTack(500, '2');
addTack(300, '3');
addTack(400, '4');
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Promise是一种用于处理异步操作的JavaScript对象。它的原理是基于事件循环和回调函数的机制。当我们创建一个Promise实例时,它会立即执行一个传入的函数,并返回一个Promise对象。这个函数又被称为executor函数,它接受两个参数resolve和reject。resolve函数用于将Promise状态从pending变为fulfilled,并传递一个值作为结果;reject函数用于将Promise状态从pending变为rejected,并传递一个原因作为错误信息。 在executor函数中,我们可以通过调用resolve和reject来改变Promise状态。当某个异步操作成功完成时,我们可以调用resolve来将Promise状态变为fulfilled,并传递异步操作的结果。而当某个异步操作失败时,我们可以调用reject来将Promise状态变为rejected,并传递一个错误原因。 Promise的优点之一是可以链式调用。通过在Promise对象上调用then方法,我们可以注册回调函数来处理Promise的结果。当Promise状态从pending变为fulfilled时,将会执行与then方法关联的回调函数,并将Promise的结果作为参数传递给回调函数。当Promise状态从pending变为rejected时,将会执行与catch方法关联的回调函数,并将错误原因作为参数传递给回调函数。通过链式调用then方法,我们可以将多个异步操作串联起来,形成一个异步操作的流水线。 总结起来,Promise的原理是通过executor函数、resolve函数和reject函数来实现异步操作的封装和处理。通过链式调用then方法,可以对Promise的结果进行处理和传递。而Promise状态变化是基于事件循环和回调函数的机制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [这一次,彻底弄懂 Promise 原理](https://blog.csdn.net/weixin_30881367/article/details/101419505)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值