Bootstrap

手写promise

手写promise

//把promise封装成一个类
class Promise{
    //构造函数
    constructor(executor){
        //添加属性
        this.PromiseState='pending';
        this.PromiseResult=null;
        //声明属性
        this.callbacks=[];
        //保存实例对象的this的值
        const self=this;
        //resolve函数
        function resolve(data){
            //判断状态 保证状态只能更改一次
            if(self.PromiseState!=='pending') return;
            // console.log(self);
            //1.修改对象的状态(promiseState)
            self.PromiseState='fulfilled';//resolved
            //2.设置对象的结果值(promiseResult)
            self.PromiseResult=data;
            //调用成功的回调函数 
            setTimeout(()=>{
                self.callbacks.forEach(item=>{
                    item.onResolved(data);
                });
            });
        }
        //reject函数
        function reject(data){
            //判断状态 保证状态只能更改一次
            if(self.PromiseState!=='pending') return;
            //1.修改对象的状态(promiseState)
            self.PromiseState='rejected';//resolved
            //2.设置对象的结果值(promiseResult)
            self.PromiseResult=data;
            //调用失败的回调函数 
            setTimeout(()=>{
                self.callbacks.forEach(item=>{
                    item.onRejected(data);
                });
            })
        }

        try{
            //同步调用 执行器函数
            executor(resolve,reject);
        }catch(e){
            //修改 promise对象的状态为失败
            reject(e);
        }
        
    }

    //then方法封装
    then(onResolved,onRejected){
        const self=this;
        //判断回调函数参数是否传值,允许catch上面的不传onRejected回调函数,定义默认的,允许第二个参数不传
        if(typeof onRejected !== 'function'){
            onRejected=reason=>{
                throw reason;
            }
        }
        //允许第一个参数不传
        if(typeof onResolved !== 'function'){
            onResolved=value=>value;
        }
        return new Promise((resolve,reject)=>{
            //封装函数 三个状态的代码除了回调都一样,封装后期好维护
            function callback(type){
                try{
                    //获取回调函数的执行结果
                    let result=type(self.PromiseResult);
                    //判断
                    if(result instanceof Promise){
                        //如果是promise类型的对象
                        //这个result指的是index.html的return的new promise
                        result.then(v=>{
                            resolve(v);
                        },r=>{
                            reject(r);
                        })
                    }else{
                        //结果的对象状态为成功
                        resolve(result);
                    }
                }catch(e){
                    reject(e);
                }
            }
    
            //调用回调函数
            if(this.PromiseState==='fulfilled'){
                setTimeout(()=>{
                    callback(onResolved);
                })
            }
            if(this.PromiseState==='rejected'){
                setTimeout(()=>{
                    callback(onRejected);
                })
            }
            //判断pending状态
            if(this.PromiseState==='pending'){
                ///保存回调函数
                this.callbacks.push({
                    onResolved: function(){
                        callback(onResolved);
                    },
                    onRejected: function(){
                        callback(onRejected);
                    }
                });
            }
        })
    }

    //catch方法
    catch(onRejected){
        return this.then(undefined,onRejected);
    }

    //resolve方法不属于实例对象,属于类,构造函数
    static resolve(value){
        //返回promise对象
        return new Promise((resolve,reject)=>{
            if(value instanceof Promise){
                value.then(v=>{
                    resolve(v);
                },r=>{
                    reject(r);
                })
            }else{
                resolve(value);
            }
        })
    }

    //reject
    static reject(reason){
        //返回一个失败的promise对象
        return new Promise((resolve,reject)=>{
            reject(reason);
        })
    }
    
    //添加all方法
    static all(promises) { 
        //返回结果为promise对象
        return new Promise((resolve,reject)=>{
            //声明变量,记录有几个promise对象成功
            let count=0;
            //声明数组,记录每个成功的peomise对象的
            let arr=[];
            //遍历
            for(let i=0;i<promises.length;i++){
                //
                promises[i].then(v=>{
                    //得知对象的状态是成功
                    //所有的promise对象都成功
                    count++;
                    //将当前promise对象成功的结果存到数组中
                    arr[i]=v;
                    if(count===promises.length){
                        resolve(arr);
                    }
                },r=>{
                    reject(r);
                })
            }
        })
    }

    //添加race方法
    static race(promises){
        //返回结果是promise对象
        return new Promise((resolve,reject)=>{
            for(let i=0;i<promises.length;i++){
                //哪个状态先改变哪个就决定结果
                promises[i].then(v=>{
                    //修改返回对象的状态为成功
                    resolve(v);
                },r=>{
                    //修改返回对象的状态为失败
                    reject(r);
                })
            }
        })
    }
}

// //声明构造函数
// function Promise(executor){
//     //添加属性
//     this.PromiseState='pending';
//     this.PromiseResult=null;
//     //声明属性
//     this.callbacks=[];
//     //保存实例对象的this的值
//     const self=this;
//     //resolve函数
//     function resolve(data){
//         //判断状态 保证状态只能更改一次
//         if(self.PromiseState!=='pending') return;
//         // console.log(self);
//         //1.修改对象的状态(promiseState)
//         self.PromiseState='fulfilled';//resolved
//         //2.设置对象的结果值(promiseResult)
//         self.PromiseResult=data;
//         //调用成功的回调函数 
//         setTimeout(()=>{
//             self.callbacks.forEach(item=>{
//                 item.onResolved(data);
//             });
//         });
//     }
//     //reject函数
//     function reject(data){
//         //判断状态 保证状态只能更改一次
//         if(self.PromiseState!=='pending') return;
//         //1.修改对象的状态(promiseState)
//         self.PromiseState='rejected';//resolved
//         //2.设置对象的结果值(promiseResult)
//         self.PromiseResult=data;
//         //调用失败的回调函数 
//         setTimeout(()=>{
//             self.callbacks.forEach(item=>{
//                 item.onRejected(data);
//             });
//         })
//     }

//     try{
//         //同步调用 执行器函数
//         executor(resolve,reject);
//     }catch(e){
//         //修改 promise对象的状态为失败
//         reject(e);
//     }
    

// }

// //添加then方法
// Promise.prototype.then=function(onResolved,onRejected){
//     const self=this;
//     //判断回调函数参数是否传值,允许catch上面的不传onRejected回调函数,定义默认的,允许第二个参数不传
//     if(typeof onRejected !== 'function'){
//         onRejected=reason=>{
//             throw reason;
//         }
//     }
//     //允许第一个参数不传
//     if(typeof onResolved !== 'function'){
//         onResolved=value=>value;
//     }
//     return new Promise((resolve,reject)=>{
//         //封装函数 三个状态的代码除了回调都一样,封装后期好维护
//         function callback(type){
//             try{
//                 //获取回调函数的执行结果
//                 let result=type(self.PromiseResult);
//                 //判断
//                 if(result instanceof Promise){
//                     //如果是promise类型的对象
//                     //这个result指的是index.html的return的new promise
//                     result.then(v=>{
//                         resolve(v);
//                     },r=>{
//                         reject(r);
//                     })
//                 }else{
//                     //结果的对象状态为成功
//                     resolve(result);
//                 }
//             }catch(e){
//                 reject(e);
//             }
//         }

//         //调用回调函数
//         if(this.PromiseState==='fulfilled'){
//             setTimeout(()=>{
//                 callback(onResolved);
//             })
//         }
//         if(this.PromiseState==='rejected'){
//             setTimeout(()=>{
//                 callback(onRejected);
//             })
//         }
//         //判断pending状态
//         if(this.PromiseState==='pending'){
//             ///保存回调函数
//             this.callbacks.push({
//                 onResolved: function(){
//                     callback(onResolved);
//                 },
//                 onRejected: function(){
//                     callback(onRejected);
//                 }
//             });
//         }
//     })

// }

// //添加catch方法
// Promise.prototype.catch=function(onRejected){
//     return this.then(undefined,onRejected);
// }

// //添加resolve方法
// Promise.resolve=function(value){
//     //返回promise对象
//     return new Promise((resolve,reject)=>{
//         if(value instanceof Promise){
//             value.then(v=>{
//                 resolve(v);
//             },r=>{
//                 reject(r);
//             })
//         }else{
//             resolve(value);
//         }
//     })
// }

// //添加reject方法
// Promise.reject=function(reason){
//     //返回一个失败的promise对象
//     return new Promise((resolve,reject)=>{
//         reject(reason);
//     })
// }

// //添加all方法
// Promise.all=function (promises) {
//     //返回结果为promise对象
//     return new Promise((resolve,reject)=>{
//         //声明变量,记录有几个promise对象成功
//         let count=0;
//         //声明数组,记录每个成功的peomise对象的
//         let arr=[];
//         //遍历
//         for(let i=0;i<promises.length;i++){
//             //
//             promises[i].then(v=>{
//                 //得知对象的状态是成功
//                 //所有的promise对象都成功
//                 count++;
//                 //将当前promise对象成功的结果存到数组中
//                 arr[i]=v;
//                 if(count===promises.length){
//                     resolve(arr);
//                 }
//             },r=>{
//                 reject(r);
//             })
//         }
//     })
// }

// //添加race方法
// Promise.race=function(promises){
//     //返回结果是promise对象
//     return new Promise((resolve,reject)=>{
//         for(let i=0;i<promises.length;i++){
//             //哪个状态先改变哪个就决定结果
//             promises[i].then(v=>{
//                 //修改返回对象的状态为成功
//                 resolve(v);
//             },r=>{
//                 //修改返回对象的状态为失败
//                 reject(r);
//             })
//         }
//     })
// }

async 和 await

async函数

  1. 函数的返回值是promise对象

  2. promise对象的结果由async函数执行的返回值决定

    //和then方法返回结果的规则是一样的
            async function main() { 
                //1.如果返回值是一个非promise类型的数据
                // return 521;
                //2.如果返回的是一个proise对象
                // return new Promise((resolve,reject)=>{
                //     // resolve('ok');
                //     reject('error')
                // })
                //3.抛出异常
                throw "fail";
            }
    
            let result=main();
    
            console.log(result);
    

await表达式

  1. await右侧的表达式一般为promise对象,但也可以是其他的值

  2. 如果表达式是promise对象,await返回的是promise成功的值

  3. 如果表达式是其他值,直接将此值作为await的返回值

    async function main(){
                let p=new Promise((resolve,reject)=>{
                    // resolve('ok');
                    reject("error");
                })
                // //1.右侧为promise的情况
                // let res=await p;
                // console.log(res);
    
                // //2.右侧为其他类型的数据
                // let res2=await 20;
                // console.log(res2);
    
                //2.如果promise是失败的状态,要用try catch拿到失败的结果
                try{
                    let res3=await p;
                }catch(e){
                    console.log(e);
                }
            }
    
            main();
    

注意

  1. await必须写在async函数中,但async函数中可以没有await
  2. 如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理

async与await结合实践:

/**
 * 读取resource文件夹下 1.html 2.html 3.html文件内容
 */

const fs=require('fs');
const util=require('util');
const mineReadFile=util.promisify(fs.readFile);//可以把这些api转成promise形态的函数

//回调函数的方式
// fs.readFile('./resource/1.html',(err,data1)=>{
//     if(err) throw err;
//     fs.readFile('./resource/2.html',(err,data2)=>{
//         if(err) throw err;
//         fs.readFile('./resource/3.html',(err,data3)=>{
//             if(err) throw err;
//             console.log(data1+data2+data3);
//         })
//     })
// })

//async和await
async function main(){
    try{
        //读取第一个文件内容
        let data1=await mineReadFile('./resource/1.html');
        let data2=await mineReadFile('./resource/2.html');
        let data3=await mineReadFile('./resource/3.html');
        console.log(data1+data2+data3);
    }catch(e){
        console.log(e.code);
    }
    
}

main();

async与await结合发送AJAX请求:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">点击获取段子</button>
    <script>
        function sendAJAX(url, method = 'GET', data = null) {
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.open(method, url, true);

                // 设置请求头,如果是POST请求且发送的数据是JSON
                if (method === 'POST' && data) {
                    xhr.setRequestHeader('Content-Type', 'application/json');
                }

                // 注册状态变化事件处理程序
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === XMLHttpRequest.DONE) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            // 请求成功,解析响应并解析Promise
                            try {
                                const response = JSON.parse(xhr.responseText);
                                resolve(response);
                            } catch (e) {
                                resolve(xhr.responseText);
                            }
                        } else {
                            // 请求失败,拒绝Promise
                            reject(new Error(`Request failed with status code ${xhr.status}`));
                        }
                    }
                };

                // 处理网络错误
                xhr.onerror = function () {
                    reject(new Error('Network error'));
                };

                // 发送请求
                if (method === 'POST' && data) {
                    xhr.send(JSON.stringify(data));
                } else {
                    xhr.send();
                }
            });
        }

        let btn=document.querySelector('#btn');

        btn.addEventListener('click',async function(){
            let data=await sendAJAX('https://jsonplaceholder.typicode.com/posts');
            console.log(data);
        })
    </script>
</body>

</html>
;