手写实现⭐


实现Promise,以及它的各种api

基础版Promise --excutor是同步的情况

class myPromise {
    constructor(excutor) {
        this.init();
        // excutor 有两个参数
        try {
            // 3.绑定this
            excutor(this.resolve.bind(this), this.reject.bind(this)); // excutor是Priomise本身的reolve等函数
        } catch (e) {
            this.reject(e)
        }
    }

    resolve(value) {
        console.log("excuting resolve functiom ")
        if (this.status === 'pending') {
            this.status = 'fullfiled'
            this.value = value;
            console.log("resovle:",this.status,this.value)
        }
    }
    reject(value) {
        if (this.status === 'pending') {
            this.status = 'reject';
            this.value = value;
        }

    }
    init() {
        this.status = "pending";
        this.value = undefined;
    }

    then(onFulFilled,onReject){
        if(this.status==="fullfiled"){
            onFulFilled(this.value)
        }
        if(this.status==="reject"){
            onReject(this.value)
        }
    }

}

let p = new myPromise((resolve,reject)=>{
    console.log("start")
    resolve("ok")}
).then(res=>{
    console.log("onFulFilled",res)
})

实现new,对new过程的理解

new的过程,实际上是创建了一个新的对象,然后这个对象执行了构造函数。

function myNew(fun){
    let args=[...arguments];
    let obj={}; // 这就是为啥构造函数里面总是this.xxx=xxx;
    obj.__proto__=fun.prototype;
    let tmpObj=fun.apply(obj,args);
    return tmpObj instanceof Object?tmpObj:obj;
}

function test(){
    this.name='name';
    // return {
    //     age:'age'
    // }
}

let t= myNew(test);
console.log(t)

实现async/await-异步方法怎么同步执行

思路是借助es6的generator实现同步等待,难点在,自动化遍历执行完所有状态。

  • generator是什么,以及特点
  • 思路:假设需要按顺序执行a1,a2,…,an的异步方法,只需要,将他们声明成generator函数里的状态即可,然后通过next,不断去调。
console.clear()
// 产生异步函数
function getAsync() {
    return function(...args) {
        return new Promise((resolve,reject)=>{
            console.log("excute",...args);
            setTimeout(()=>{
                console.log("resolve",...args);
                resolve(...args)
            }, Math.random() * 1000)
        }
        )
    }
}
// 定义两个异步函数
let a1 = getAsync();
let a2 = getAsync();

// 声明异步函数,同步执行的顺序
function* generator(apis) {
    let i=0;
    for (let api of apis) {
        i++;
        yield api(i);
    }
}
// 自动化执行函数
function myAsync(generator) {
    return new Promise((resolve,reject)=>{
        let ge = generator;
        let args = [...arguments];
        // 获取generator中的状态
        let next = function(...args) {// args是上一个状态的返回值
            let result = ge.next(...args);// 执行当前yeild
            if (result.done){ // 结束
                return resolve("all done") 
            }
            // 难点:等当前状态返回后,触发下一次
            result.value.then(res=>{ // 获取当前状态的返回值,本题中,result.value是一个promise对象,通过then获取当前状态的返回值。
                // 取出本次的结果,当做参数
                next(res);
            }
            );
        }
        next()
    }
    )
}

// main
let gen = generator([a1, a2]);
myAsync(gen).then(res=>{
    console.log(res) // 输出end
})

难点

  • 借助generator函数
  • 怎么触发下一次函数?
    • next不会阻塞主线程!
    • 需要等待上一次的结果返回(then中触发下一次)
  • 怎么结束? done

手写call apply bind

call和bind的区别就是,参数传入不同。两者都会立刻执行
fun.call(this,…args);
fun.apply(this,[…agrs]);
bind返回的是一个函数,不会立刻执行。

call

  • 其实应该考虑没有传入context的情况,但面试考点一般不在这儿.所以,这里就直接写核心
Function.prototype.myCall=function(context){
    let args=[...arguments].slice(1);
    context.fn=this; // fn调用myCall,通过this获取fn
    context.fn(...args)// 难点:要求执行fn的时候,this指向context;参数展开传入
    delete context.fn;
}

apply

  • 比起call,就注意一下参数而已
Function.prototype.myApply=function(context){
    let args=[...arguments].slice(1); // 二维数组
    let arr=args[0];
    let fn=this;
    context.fn=fn;
    context.fn(...arr)
    delete context.fn;
}

bind

Function.prototype.myBind=function(context){
    // 1.返回的是函数
    // 2.这个函数运行的时候,this指向context
    // 3.可以多次传参
    let arg1=[...arguments].slice(1);
    let fn=this;

    return function(...args){ // 你怎么保证不立刻执行?
        return fn.apply(context,[...arg1,...args])
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值