Promise的总结

Promise的总结

(1)什么是同步,异步?

同步表示需要前一个任务完成之后,才会执行下一个任务,简而言之,就是上一行代码执行返回结果后,才会执行下一行代码(好理解)

异步表示异步任务启动后,会继续向下执行,等到同步代码执行结束之后才执行回调函数;

//异步执行
    function func1() {
            console.log('start');
            setTimeout(()=>{
                console.log('i am callback');
            },3000);
            console.log('end');

        }
//这个函数会先执行console.log('start')-,接着执行setTimeout(),但是setTimeout()里面的回调函数是一个异步函数,所以先放起来,继续执行后面的console.log('end');然后发现所有的同步代码执行完毕后,再去执行setTimeout()里面的回调函数,这里需要注意的是不是不执行setTimeout,而是里面的异步的回调函数不执行
// 因此 打印的顺序为 start end 然后等3秒之后打印出 i am callback

(2)回调函数

回调函数是ES5里面解决异步顺序的一种方法,但是这种方法的可读性很差,当出现回调函数层层嵌套的情况时,可维护性差,可读性差,也就是出现了所谓的回调地狱。

    function fn(cb) {
        setTimeout(() => {
            cb();
        }, 1000);
    }

    fn(function () {  // 回调地狱 ;
        console.log(111);
        fn(function () {
            console.log(222);
            fn(function () {
                console.log(333);
                fn(function () {
                    console.log(444);
                })
            })
        })
    })

如何解决回调地狱的问题呢:

(1)Es6中的Promise

(2)async await

(3)观察者模式

(3)Promise

resolve和reject方法

1.pending 没有任何操作
2.resolved/fulfilled 成功的状态
3.rejected 失败的状态

    function fn(){
        let  p = new Promise((resolve,reject)=>{
        })
        console.log(p);
    }

在这里插入图片描述

//  resolve()函数的作用就是将PromiseState从pending状态更新为fulfilled的状态,resolve(param)的参数会作为[[PromiseResult]]的值
function fn1(){
        let  p = new Promise((resolve,reject)=>{
            resolve()
        })
        console.log(p);
    }

function fn2(){
        let  p = new Promise((resolve,reject)=>{
            resolve(123)
        })
        console.log(p);
    }

resolve()
resolve(124)

//  reject()函数的作用就是将PromiseState从pending状态更新为 rejected的状态, rejected(param)的参数会作为[[PromiseResult]]的值
function fn1(){
        let  p = new Promise((resolve,reject)=>{
             reject(param)
        })
        console.log(p);
    }

then方法

每一个promise对象都会有一个then方法
then方法里有2个回调函数,onResolved和onRejected。

1.onResolved: 在调取 resolve函数的时候执行  (then里的第一个回调函数)
            promiseState : fufilled 状态的时候
            promiseResult: 作为 onResolved函数的参数; 
 2.onRejected : 在调取reject 函数的时候执行;(then里的第二个回调 函数);
             promiseState : rejected 状态的时候
             promiseResult: 作为 onRejected函数的参数;

1.onResolved回调函数 参数 是promiseResult的结果值;

代码如下:

  /* 
    调用 resolve 的时候  promiseState 变成 fufilled状态  
    promiseResult 是传递的参数 data
   */
    function fn(){
        let p = new Promise((resolve, reject) => {
            const data = '1234'
            resolve(data);
        })
        console.log(p);
        p.then(function (res) {   // 是成功状态的promise对象的promiseResult结果值;
            console.log("onResolved执行了", res);
        }, function () {
            console.log("onRejected执行了");
        });
    }
    

在这里插入图片描述

//  resolve函数在异步回调里面,所以先执行同步语句,然后在执行异步语句,所以执行同步语句console.log(p)的时候,还没有执行resolve,p的状态还是pending,然后在多
function fn(){
        let p = new Promise((resolve, reject) => {
            
            setTimeout(() => {
                const data = '1234'
                resolve(data);
                // reject("错误");
            }, 2000);

        })
        console.log(p);
        p.then(function (res) {   // 是成功状态的promise对象的promiseResult结果值;
            console.log("onResolved执行了", res);
        }, function () {
            console.log("onRejected执行了");
        });
    }

在这里插入图片描述

catch方法

在这里插入图片描述

如果catch之前的任意一个阶段发生了错误,那么就会触发catch,之后的then就不会被执行,这个和同步编程里面用到的try…catch…块很相似。

Promise用法技巧

(1)

在这里插入图片描述

上面这种写法会打破两个promise的并行,他会等到第一个任务执行完毕之后才执行第二个任务,更高效的写法是用promise.all组合起来,然后再去 await,修改后的程序运行效率会提升一倍。

在这里插入图片描述

(2)如果我们希望等待循环中所有的异步操作都执行完毕后再继续执行后面的代码,是不能直接使用forEach或者map这一类方法的,如下图,尽管我们在回调函数中写了await,但是这里的forEach会立刻返回,他并不会暂定等到所有的异步方法都执行完毕。

在这里插入图片描述
如果我们希望等待循环中所有的异步操作都执行完毕后再继续执行后面的代码,正确的写法还是应该使用传统的for循环。
在这里插入图片描述
更进一步,如果我们想要循环中的所有操作都并发执行的话,一种更炫酷的写法就是使用for await,
在这里插入图片描述

重点,宏任务,微任务,同步,异步,Event Loop模型以及执行顺序

js是单线程(自上而下执行代码),因此一个任务时间过长,势必会造成线程堵塞,影响渲染效率;

随着Promise的引入,JavaScript引擎自身也能够发起异步任务了,于是,js任务就分为了同步任务和异步任务,异步任务由进一步划分为 宏任务微任务,所以说宏任务微任务都是异步任务的范畴。

微任务执行比较快,一次可以执行很多个,在当前宏任务执行后立刻清空微任务可以达到伪同步的效果,这对视图渲染效果起到至关重要的作用,这也是区分宏任务、微任务的原因。

宏任务的微任务的基本类型

new Promise()内部的代码是同步任务

宏任务:setTimeout(), setInterVal() ,异步Ajax请求

微任务:Promise.then(), Promise.catch()和Promise.finally(),process.nextTick()

宏任务和微任务执行过程

先执行同步代码,遇到异步宏任务就放到宏任务队列中,遇到异步微任务就放到异步微任务队列中,当所有的同步代码执行完毕后,将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环到所有的任务执行完毕。

console.log('1');
 
setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})
setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
1)执行第一行的同步任务,打印1

2)第一个setTimeout加入任务队列宏任务区,记为s1

3)第15行的process.nextTick是异步任务中的微任务,加入微任务区,记为n1

4)第18行的promise是同步任务,打印7,其后的.then是微任务,加入微任务区,记为t1

5)第24行的setTimeout加入任务队列宏任务区,记为s2。至此,同步代码执行完毕。

6)执行微任务区中的任务,n1打印6,t1打印8。至此,微任务区任务执行完成

7)执行宏任务区s1,打印2,其内process.nextTick放入微任务区,记为n2,其后promise为同步任务,立即执行打印4,将后续.then微任务放入微任务区记为t2

8)继续执行微任务区,n2打印3,t2打印5

9)执行第二个setTimeout,直接打印9,其内process.nextTick放入微任务区,记为n3,其后promise为同步任务,立即执行打印11,将后续.then微任务放入微任务区记为t3

10)执行微任务,n3打印10,t3打印12

最终打印结果为:1、7、6、8、2、4、3、5、9、11、10、12

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值