promise设计思路以及原理

第一次总结
1、将resolve、reject 加入到微任务中去了 微任务 如果没有返回结果那么将一直存在于任务对列当中 如果有返回结果则放入到了事件执行队列当中去了
2、链式调用 拓展 then方法,当new promise时 如果执行了resolve或者reject 那么将会吧执行结果存放于变量中(data) 而 then拓展方法通过this能够获取到data
这样就可以在then里面做自定义操作了,并且then返回的是一个 promise对象 而 返回的promise对象里也有then的方法所以可以一直链式调用
3、promise不可中断,如果自己写的可以,因为不知道在promise里面写的异步方法是什么
第二次总结
第二次仔细想的时候发现 第一次的总结被完全推翻了
原理重点是他的 异步队列的设计 onResolvedCallback (成功队列) onRejectedCallback (失败队列)
1.promise异步成功后执行 resolve 或者是 reject 执行成功之后会直接执行 异步队列里面的函数而异步队列里面的函数就是你then里面push进去的执行函数 onResolved,onRejected 在执行 resolve 之前会开启一个微任务(未知)让同步代码先行执行 (为的就是要then里面传入的 成功 或者 失败函数先加入至异步队列里面去)加入队列成功之后会遍历异步队列 执行加入的函数
2.then函数里面将传入的函数 push到异步队列里面去 并且 返回一个promise 方便之后的then的链式调用

代码参考 https://www.jianshu.com/p/b4f0425b22a1



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Promise手动实现</title>
</head>
<body>
    
</body>
<script>
   
    
    //手动实现promise
    function myPromise(cb){  //参数为一个函数,接收resolve, reject两个参数
        const self = this;
        self.status = 'pending';
        self.data = undefined;
        self.onResolvedCallback = [];
        self.onRejectedCallback = [];
        function resolve(value){
            console.log('我是同步的resolve')
            setTimeout(() => {  //这里异步执行,否则会直接执行掉
                console.warn('开始执行异步resolve')
                if(self.status == 'pending'){
                    self.status = 'fulfilled'
                    self.data = value;
                    console.log(self.onResolvedCallback)
                    self.onResolvedCallback.map(item => {item(value)})
                }
            })
            
        }
        function reject(reason){
            setTimeout(() => {
              if(self.status == 'pending'){
                self.status = 'failed'
                self.data = reason;
                self.onResolvedCallback.map(item => {item(value)})
              }
            })
        }
        try  {
            cb(resolve,reject)
        } catch(e) {
            reject(e)
        }
    }
    //基本的then方法
    // myPromise.prototype.then = function(onResolve, onReject){
    //     this.onResolvedCallback.push(onResolve);
    //     this.onRejectedCallback.push(onReject)
    // }
    //由于then要返回Promise对象,所以对then方法进行如下改造
    myPromise.prototype.then = function(onResolved,onRejected){
        console.log('我是promise的then')
        const self = this;
        let promise2;
        //判断是不是onResolved,onRejected函数
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : value => value;
        //判断promise对象的当前状态
        if(self.status == 'fulfilled'){
            console.log('异步调用promise或者多次调用,这里已经解析了')
            promise2 = new myPromise(function(resolve,reject){
                try{
                    let x = onResolved(self.data)
                    //判断onResolved是否返回一个myMromise对象
                    if(x instanceof myPromise){
                        x.then(resolve,reject)
                    } else {
                        resolve(x)
                    }
                }catch(e){
                    reject(e)
                }
            })
            return promise2;
        }
        if(self.status == 'failed'){
            promise2 = new myPromise(function(resolve,reject){
                try{
                    let x = onRejected(self.data)
                    if(x instanceof myPromise){
                        x.then(resolve,reject)
                    } else {
                        resolve(x)
                    }
                }catch(e){
                    reject(e)
                }
            })
        }
        //promise对象当前状态为pending,此时并不能确定调用onResolved还是onRejected,需要等当前Promise状态确定。
        
        if(self.status == 'pending'){
            promise2 = new myPromise(function(resolve, reject){
                //向数组添加函数并不会执行该函数,执行过push同步任务后,会执行异步任务setTimeout
                self.onResolvedCallback.push(function(value){
                    try{
                        // console.error('我是promise的pending状态',self.status)
                        // console.log('pending状态下的self.data',self.data)
                        let x = onResolved(self.data)
                        if(x instanceof myPromise){
                            x.then(resolve,reject)
                        }else{
                            console.log('x不是 promise:',x)
                            resolve(x)
                        }
                    }catch(e){
                        reject(e)
                    }
                })
 
                self.onRejectedCallback.push(function(value){
                    try{
                        let x = onRejected(self.data)
                        if(x instanceof myPromise){
                            x.then(resolve,reject)
                        }else{
                            resolve(x)
                        }
                    }catch(e){
                        reject(e)
                    }
                })
                
            })
            return promise2
        }
 
    }
    const promise = new myPromise((resolve) => {
        resolve(1); //resolve函数内部的执行是异步的 会先去执行promise.then()这个同步函数
    });
    promise.then(data => {
        console.log(data)
    })
    promise.then(a=> console.log(a));
    //then方法的返回值是下次promise then中的值
    const test = promise.then(data => {
        console.log('返回一个promise对象',data)
    });
    test.then(data => {
        console.log('我是二次返回promise data',data)
    })
    // const test2 = promise.then();
    // console.log('我在then中什么都没传',test2)
 
 
 
 
 
</script>
</html>

  

posted @ 2020-09-27 09:40  laowang666888  阅读(266)  评论(0编辑  收藏  举报