web前端--promise规范及应用

本文详细介绍了Promise的用法和规范,包括任务队列、异步任务、微任务与宏任务的概念,以及Promise的三种状态和状态流转。强调了then方法的使用规则及其返回值特性,并探讨了如何手写Promise以及在面试中常见的Promise相关问题。
摘要由CSDN通过智能技术生成

课程目标:
i.掌握promise的用法和原理、规范
ii.相关面试题和例题的掌握
iii.generator的初步了解

在了解promise之前,需要有一些前置基本知识点

1、任务队列(消息队列)

​ 就是一个队列的数据结构,里面存放要执行的任务

​ 任务队列的任务类型有鼠标滚动、点击、移动、计时器、websocket、文件的读写、DOM解析、样式计算、布 局计算、js的执行等等

​ 上述任务都在主线程中执行,由于js单线程的机制,一个任务得等它前面的任务都执行完毕它才能执行,可能会遇到单个任务执行时间过长,一直占用主线程的情况。

​ 具体的业务场景:对于频繁改变DOM元素的js任务来说,每次变化都需要调用不同的js接口,导致任务的时间拉长,而如果把这个任务做成异步执行,在添加到任务队列之前,它前面也可能存在很多任务的排队

​ 所以,为了处理高优先级的任务,解决单线程任务执行时间过长的问题,将任务切分为宏任务和微任务

2、异步任务

​ 在进程执行某个任务时,任务要等待一段时间才能返回,所以就把这个任务放到专门处理异步任务的模块,继续执行任务队列中的其他模块,防止消息队列发生阻塞。

​ 常见的异步任务:定时器、ajax、事件绑定、async await、promise

3、微任务和宏任务

​ 任务队列中的每一个任务都是宏任务,在执行的过程中,如果有微任务产生,就添加到微任务队列中去

异步请求(如超时报错等功能 具有很多的应用场景)

宏任务 微任务
渲染事件 promise[then/catch/finally]
请求 proxy
script代码块 MutationObserver
setTimeout process.nextTick
setInterval queueMicrotask(用来创建微任务)
setimemediate/ I/O async/await

注意:当前宏任务里的微任务全部执行完,才会执行下一个宏任务,构成一个事件循环(执行都是把任务压入执行栈来执行对应的函数操作的)
在这里插入图片描述

事件执行的具体例子1:

function bar() {
   
  console.log('bar');
  Promise.resolve().then((str) => console.log('micro-bar'));
  setTimeout((str) => console.log('macro-bar'), 0);
}
function foo() {
   
  console.log('foo');
  Promise.resolve().then((str) => console.log('micro-foo'));
  setTimeout((str) => console.log('macro-foo'), 0);
  bar();
}
foo();
console.log('global');
Promise.resolve().then((str) => console.log('micro-global'));
setTimeout((str) => console.log('macro-global'), 0);

//执行结果
foo
bar
global
micro-foo
micro-bar
micro-global
macro-foo
macro-bar
macro-global

在这里插入图片描述

具体例子2:

<script>
    console.log(1)
	setTimeout(()=>{
   
        console.log(2)
    })
	new Promise(resolve=>{
   
        setTimeout(()=>{
   
            console.log(3)
        })
        resolve(4)
        console.log(5)
    }).then(num=>{
   
        console.log(num)
    })
	function(a){
   
    	console.log(6)
	}
	async function b(){
   
        await a()
        console.log(7)
    }
	b()
	console.log(8)
</script>
//注意:上面的await a() 等价于new Promise(()=>{a()}).then(()=>{console.log(7)})
//执行结果:1 5 6 8 4 7 2 3

常见的术语:

1、promise (是一个有then方法的对象或者函数,行为遵循一定的规范)

2、thenable,是一个有then方法的函数或者对象

3、value,promise状态成功的值,是resolve的参数,可以是number,boolean,undefined,promise类型

4、reason,promise状态失败时的值,是reject的参数,表示拒绝的原因

5、exception 异常值

规范:有三种状态

1、pending

1-1、初始的状态,可以改变

1-2、一个promise在resolve/reject之前都处于这个状态

1-3 resolve :pending -> fulfilled状态

1-4 reject: pending -> rejected

2、fulfilled

2-1 最终态,不可变

2-2 一个promise被resolve会变成这个状态

2-3 必须拥有一个value值

3、rejected

3-1 最终态,不可变

3-2 一个promise被reject会变成这个状态

3-3 必须拥有一个reason值

状态流转

pending ->resolve(value) -> fulfilled

pending ->reject(reason) -> rejected

then

promise应该提供一个then方法,用来访问最终的结果

例子:promise.then(onFulfilled,onRejected)

1、参数要求

1.1 onFulfilled必须是一个函数类型 如果不是函数,应该被忽略(传参不是函数,就会给一个默认值)

1.2 onRejected必须是一个函数类型 如果不是函数,应该被忽略(传参不是函数,就会给一个默认值)

2、onFulfilled 特性

2.1 在promise变成fulfilled时,应该调用onFulfilled 参数是value

2.2 在promise变成fulfilled之前,不应该被调用

2.3 只能被调用一次

3、onFulfilled 特性

3.1 在promise变成rejected时,应该调用onRejected 参数是reason

3.2 在promise变成rejected之前,不应该被调用

3.3 只能被调用一次

4、onFulfilled、onRejected两者的执行环境都是在微任务里面

微任务是优选调用队列中的部分任务

setTimeout是宏任务

queueMicrotask()用来将微任务放到微任务队列中执行,缺点是兼容性一般

5、then方法可以被调用多次

promise.then(cb1,cb2);

promise.then(cb1,cb2);

promise.then(cb1,cb2);

5.1 promise状态变成filfilled后,所有的onFulfilled回调都需要按照then的顺序执行

当创建数组时发现页面卡了 才去考虑细节、底层的性能优化

[onFulfilled1,onFulfilled2,onFulfilled3]

5.2 promise状态变成rejected后,所有的onRejected回调都需要按照then的顺序执行

  1. 返回值

    then的返回值应该是一个新的Promise

    const promise1 = new Promise();

    const promise2 = promise1.then(cb1,cb2).then().then();

    两者是两个不同的实例,这种是链式调用(最后的最新的promise状态是最后一个then执行之后的结果)

    6.1 onFulfilled或者onRejected执行结果为x,调用resolvePromise() 把Promise包成一个基本类

    6.2 onFulfilled或者onRejected执行结果报错,promise2需要被reject

    6.3 onFulfilled或者onRejected不是一个函数时,promise2以promsi

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值