Promise【解决回调的方案】

Promise

解决回调地狱

1.封装fs模块

const { rejects } = require("assert");
const fs = require("fs");
const { resolve } = require("path");

function get(path){
    return new Promise((resolve,rejects)=>{
        fs.readFile(path,'utf-8',(err,data)=>{
            if (err){
                rejects(err);
            }
            resolve(data);
        })
    })
}

get("./content.txt").then(value=>{
    console.log(value.toString());
},reason=>{
    console.log(reason);
}
)

util.promisify

const util = require("util");

const fs =require("fs");

let get = util.promisify(fs.readFile);

get('./content.txt').then(
    value=>{
        console.log(value.toString());
    }
)

2.封装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>
    <script>
        function send(url){
            return new Promise((resolve,rejects)=>{
                const xhr = new XMLHttpRequest();

                xhr.open("GET",url);
                xhr.send();
                xhr.addEventListener("readystatechange",()=>{
                    if (xhr.readyState===4){
                        if (xhr.status >=200 && xhr.status <300){
                            resolve(xhr.response);
                        }else{
                            rejects(xhr.status);
                        }
                    }
                })
            })
        }
        send("http://localhost:8030/serve").then(value=>{
            console.log(value);
        },reason=>{
            console.log(reason);
        })
    </script>
</body>
</html>

3.Promise 有三种状态:

pending (等待态)

fulfiled (成功态)

rejected (失败态)

Promise 状态的转变是不可逆且只能发生一次

也就是说,一个 Promise 不能从 fulfiled 状态变回 pending 状态,也不能从 rejected 状态变为

pending 或者 fulfiled 状态

一旦 Promise 从 pending 状态变为 fulfiled 或 rejected ,它就永远不会再改变

4.Promise方法

//executor执行器,立即执行
let p = new Promise((resolve,reject)=>{
    console.log(111);
})
console.log(222);

1.Promise.resolve方法

如果传入的参数为非类型的对象,则返回的结果为成功的Promise对象

如果传入的参数为对象。则参数的结果决定了resolve的结果

let p1 =Promise.resolve(5222);

console.log(p1);

2.Promise.reject方法

返回一个失败的Promise对象

let p2 = Promise.reject("sdalds");

console.log(p2);

3.Promise.all方法

(promises) => {}

包含n个promise的数组

说明:返回一个新的promise,只有所有的promise都成功才成功

const pro1 = new Promise((resolve,reject)=>{
    resolve("OK");
})
const pro2 = new Promise((resolve,reject)=>{
    resolve("OK");
})
const pro3 = new Promise((resolve,reject)=>{
    resolve("OK");
})

let res = Promise.all([pro1,pro2,pro3]);

console.log(res);

4.Promise.race方法

返回一个新的promise,返回的是第一个完成的promise

Promise关键问题

改变对象状态

let p = new Promise((resolve,reject)=>{
    //pending=>fulfilled
    resolve("ok");
    //pending=>rejected
    reject("error")
    //pending=>rejected
    throw 'error';
})
console.log(p);

多次回调,状态改变会调用

let p = new Promise((resolve,reject)=>{
    resolve("ok");
})
p.then(value=>{
    console.log(value);
})
p.then(value=>{
    alert("1")
})

then

then的返回结果是由指定的回调函数的执行结果决定的

        let p = new Promise((resolve,reject)=>{
            resolve("ok");
        })

        p.then(value =>{
            console.log(1);
            //1
            throw "错误";
            //2
            return "sdad";
            //3new 的promise对象的返回结果是then返回promise对象的结果
            return new Promise((resolve,reject)=>{resolve("ok");})
        },reson=>{
            console.log(2);
        })

promise异常穿透

在后面使用catch

let p = new Promise((resolve,reject)=>{
    resolve("ok");
})

p.then(value =>{
    console.log(1);
},reson=>{
    console.log(2);
}).then(value=>{
    console.log(value);
}).then(value=>{
    console.log(value);
}).catch(reason=>{
    console.log(reason);
})

中断promise链

p.then(value =>{
    console.log(1);
    //唯一方法
    return new Promise(()=>{});
},reson=>{
    console.log(2);
}).then(value=>{
    console.log(value);
}).then(value=>{
    console.log(value);
}).catch(reason=>{
    console.log(reason);
})

5.自定义封装

/* 封装为一个类 */
class promise{
        constructor(executor){
            //1.修改属性
        this.PromiseState = 'pending';
        //2.设置结果
        this.PromiseResult = 'null';
        this.callbacks=[];
        /* 保存实例对象值 */
        const self = this;
        function resolve(data){
            if (self.PromiseState !== 'pending') return;
            self.PromiseState = 'fulfilled';
            self.PromiseResult = data;
    /*         if (self.callback.onReadySolve){
                self.callback.onReadySolve(data);
            } */
            setTimeout(()=>{
            self.callbacks.forEach((item)=>{
                item.onReadySolve(data);
                });
            });
        }
        //reject
        function reject(data){
            if (self.PromiseState !== 'pending') return;
            self.PromiseState = 'rejected';
            self.PromiseResult = data;
    /*         if (self.callback.OnRejected){
                self.callback.OnRejected(data);
            } */
            setTimeout(()=>{
            self.callbacks.forEach((item)=>{
                item.OnRejected(data);
                });
            });
        }
        //同步调用
        try {
            executor(resolve,reject);
        } catch (e) {
            reject(e);
        }
    }

    then(onReadySolve,OnRejected){
        //调用回调函数
    const self = this;
    if (typeof OnRejected !== 'function'){
        OnRejected = reason=>{
            throw reason;
        }
    }
    if (typeof onReadySolve !== 'function'){
        onReadySolve = value => value;
    }
    return new promise((resolve,reject)=>{
            /* 保存this */
            const self = this;
            function callback(type){
                try {
                    let result1 = type(self.PromiseResult);
                    if (result1 instanceof promise){
                        result1.then(v=>{
                            resolve(v);
                        },r=>{
                            reject(r)
                        })
                    }else{
                        resolve(result1);
                    }
                } catch (e) {
                    reject(e);
                }
            }
            if (this.PromiseState === 'fulfilled'){
                setTimeout(()=>{
                    callback(onReadySolve);
                })
            }
            if (this.PromiseState === 'rejected'){
                setTimeout(()=>{
                    callback(OnRejected);
                })
            }
            if (this.PromiseState === 'pending'){
                //保存回调
                this.callbacks.push( {
                    onReadySolve:function(){
                        callback(onReadySolve);
                    },
                    OnRejected:function(){
                        callback(OnRejected);
                    }
                })
            }
        });
    }

    catch = function(OnRejected){
        return this.then(undefined,OnRejected);
    };

    static resolve = function(value){
        return new promise((resolve,reject)=>{
            if (value instanceof promise){
                value.then(v=>{
                    resolve(v);
                },r=>{
                    reject(r);
                })
                
            }else{
                resolve(value);
            }
        });
    }

    all = function(promises){
        return new promise((resolve,reject)=>{
            let count=0;
            let arr =[];
            for (let i=0;i<promises.length;i++){
                promises[i].then(v=>{
                    /* 每个都成功都 */
                    //resolve()
                    count++;
                    arr[i]=v;
                    if (count===promises.length){
                        /* 调用resolve修改状态 */
                        resolve(v)
                    }
                },r=>{
                    reject(r);
                })
            }
        });
    }

    static reject = function(reason){
        return new promise((resolve,reject)=>{
            reject(reason);
        });
    }

    /* race方法 */
    race = function(promises){
    return new promise((resolve,reject)=>{
        let count=0;
        let arr =[];
        for (let i=0;i<promises.length;i++){
            promises[i].then(v=>{
                resolve(v)
            },r=>{
                reject(r);
            })
        }
    });
    }
}

6.async

async function main(){
    return new Promise((resolve,reject)=>{
        //resolve("OK");
        reject("ERROR");
    })
    throw "DZ";
}

let result = main();

console.log(result);

await

await必须写在async里,但是async里可以没有await

如果await的promise失败了,就会抛出异常,需要通过try catch捕获处理

            let p = new Promise((resolve,reject)=>{
                //resolve("OK");
                reject("ERROR");
            })

/*             let res = await p;
            console.log(res);

            let res2 = await 20;
            console.log(res2); */
            try {
                let res = await p;
            } catch (e) {
                console.log(e);
            }    
        }

结合案例

const fs = require("fs");
const util = require("util")
const minereadfile = util.promisify(fs.readFile);
/* fs.readFile("../res/1.html","utf-8",(err,datastr1)=>{
    if (err) throw err;
    fs.readFile("../res/2.html","utf-8",(err,datastr2)=>{
        if (err) throw err;
        fs.readFile("../res/3.html","utf-8",(err,datastr3)=>{
            if (err) throw err;
            console.log(datastr1+"  "+datastr2+"   "+datastr3);
        })
    })
}) */

async function main(){
    let datastr1 = await minereadfile("../res/1.html");
    let datastr2 = await minereadfile("../res/1.html");
    let datastr3 = await minereadfile("../res/1.html");
    console.log(datastr1+"  "+datastr2+"   "+datastr3);
}

main();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值