资讯专栏INFORMATION COLUMN

JavaScript之实现一个简单的promise

zhaofeihao / 760人阅读

摘要:本文博客原文地址我们在开发过程中大多会用到,想必大家对的使用都很熟练了,今天我们就来实现一个简单的,实现的效果如有出入还往指正。对象的状态不受外界影响。对象代表一个异步操作,有三种状态进行中已成功和已失败。

本文博客原文地址

我们在开发过程中大多会用到promise,想必大家对promise的使用都很熟练了,今天我们就来实现一个简单的promise,实现的效果如有出入还往指正。

整体结构

我们先来梳理一下整体的结果,以便后续好操作

class MyPromise {
    constructor(fn){
        
    }
    resolve(){

    }
    then(){

    }
    reject(){

    }
    catch(){

    }
}
Promise理论知识
摘抄至 http://es6.ruanyifeng.com/#do...

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

总结一下就是promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),还有就是状态的改变只能是pending -> fulfilled 或者 pending -> rejected,这些很重要

实现构造函数

现在我们开始实现构造函数

class MyPromise {
    constructor(fn){
        if(typeof fn !== "function") {
            throw new TypeError(`MyPromise fn ${fn} is not a function`)
        }
        this.state = "pending";
        this.value = void 0;
        fn(this.resolve.bind(this),this.reject.bind(this))
    }
    ...
}

构造函数接收一个参数fn,且这个参数必须是一个函数,因为我们一般这样使用new Promise((resolve,reject)=>{});
然后初始化一下promise的状态,默认开始为pending,初始化value的值。
fn接收两个参数,resolvereject

resolve
class MyPromise {
    constructor(fn){
        if(typeof fn !== "function") {
            throw new TypeError(`MyPromise fn ${fn} is not a function`)
        }
        this.state = "pending";
        this.value = void 0;
        fn(this.resolve.bind(this),this.reject.bind(this))
    }
    resolve(value){
        if(this.state !== "pending") return;
        this.state = "fulfilled";
        this.value = value
    }
    ...
}

resolve执行,接收到一个值之后;状态就由 pending -> fulfilled;当前的值为接收的值

reject
class MyPromise {
    constructor(fn){
        if(typeof fn !== "function") {
            throw new TypeError(`MyPromise fn ${fn} is not a function`)
        }
        this.state = "pending";
        this.value = void 0;
        fn(this.resolve.bind(this),this.reject.bind(this))
    }
    resolve(value){
        if(this.state !== "pending") return;
        this.state = "fulfilled";
        this.value = value
    }
    reject(reason){
        if(this.state !== "pending") return;
        this.state = "rejected";
        this.value = reason
    }
}

reject执行,接收到一个值之后;状态就由 pending -> rejected;当前的值为接收的值

then
class MyPromise {
    constructor(fn){
        if(typeof fn !== "function") {
            throw new TypeError(`MyPromise fn ${fn} is not a function`)
        }
        this.state = "pending";
        this.value = void 0;
        fn(this.resolve.bind(this),this.reject.bind(this))
    }
    resolve(value){
        if(this.state !== "pending") return;
        this.state = "fulfilled";
        this.value = value
    }
    reject(reason){
        if(this.state !== "pending") return;
        this.state = "rejected";
        this.value = reason
    }
    then(fulfilled,rejected){
        if (typeof fulfilled !== "function" && typeof rejected !== "function" ) {
            return this;
        }
        if (typeof fulfilled !== "function" && this.state === "fulfilled" ||
            typeof rejected !== "function" && this.state === "rejected") {
            return this;
        }
        return new MyPromise((resolve,reject)=>{
            if(fulfilled && typeof fulfilled === "function" && this.state === "fulfilled"){
                let result = fulfilled(this.value);
                if(result && typeof result.then === "function"){
                    return result.then(resolve,reject)
                }else{
                    resolve(result)
                }
            }
            if(rejected && typeof rejected === "function" && this.state === "rejected"){
                let result = rejected(this.value);
                if(result && typeof result.then === "function"){
                    return result.then(resolve,reject)
                }else{
                    resolve(result)
                }
            }
        })
    }
}

then的实现比较关键,首先有两个判断,第一个判断传的两个参数是否都是函数,如果部不是return this执行下一步操作。
第二个判断的作用是,比如,现在状态从pending -> rejected;但是中间代码中有许多个.then的操作,我们需要跳过这些操作执行.catch的代码。如下面的代码,执行结果只会打印1

new Promise((resolve,reject)=>{
    reject(1)
}).then(()=>{
    console.log(2)
}).then(()=>{
    console.log(3)
}).catch((e)=>{
    console.log(e)
})

我们继续,接下来看到的是返回了一个新的promise,真正then的实现的确都是返回一个promise实例。这里不多说

下面有两个判断,作用是判断是rejected还是fulfilled,首先看fulfilled,如果是fulfilled的话,首先执行fulfilled函数,并把当前的value值传过去,也就是下面这步操作,res就是传过去的value值,并执行了(res)=>{console.log(res)}这段代码;执行完成之后我们得到了result;也就是2这个结果,下面就是判断当前结果是否是一个promise实例了,也就是下面注释了的情况,现在我们直接执行resolve(result);

new Promise((resolve,reject)=>{
    resolve(1)
}).then((res)=>{
    console.log(res)
    return 2
    //return new Promise(resolve=>{})
})

剩下的就不多说了,可以debugger看看执行结果

catch
class MyPromise {
    ...
    catch(rejected){
        return this.then(null,rejected)
    }
}
完整代码
class MyPromise {
    constructor(fn){
        if(typeof fn !== "function") {
            throw new TypeError(`MyPromise fn ${fn} is not a function`)
        }
        this.state = "pending";
        this.value = void 0;
        fn(this.resolve.bind(this),this.reject.bind(this))
    }
    resolve(value){
        if(this.state !== "pending") return;
        this.state = "fulfilled";
        this.value = value
    }
    reject(reason){
        if(this.state !== "pending") return;
        this.state = "rejected";
        this.value = reason
    }
    then(fulfilled,rejected){
        if (typeof fulfilled !== "function" && typeof rejected !== "function" ) {
            return this;
        }
        if (typeof fulfilled !== "function" && this.state === "fulfilled" ||
            typeof rejected !== "function" && this.state === "rejected") {
            return this;
        }
        return new MyPromise((resolve,reject)=>{
            if(fulfilled && typeof fulfilled === "function" && this.state === "fulfilled"){
                let result = fulfilled(this.value);
                if(result && typeof result.then === "function"){
                    return result.then(resolve,reject)
                }else{
                    resolve(result)
                }
            }
            if(rejected && typeof rejected === "function" && this.state === "rejected"){
                let result = rejected(this.value);
                if(result && typeof result.then === "function"){
                    return result.then(resolve,reject)
                }else{
                    resolve(result)
                }
            }
        })
    }
    catch(rejected){
        return this.then(null,rejected)
    }
}
测试
new MyPromise((resolve,reject)=>{
    console.log(1);
    //reject(2)
    resolve(2)
    console.log(3)
    setTimeout(()=>{console.log(4)},0)
}).then(res=>{
    console.log(res)
    return new MyPromise((resolve,reject)=>{
        resolve(5)
    }).then(res=>{
        return res
    })
}).then(res=>{
    console.log(res)
}).catch(e=>{
    console.log("e",e)
})
执行结果:
> 1
> 3
> 2
> 5
> 4

原生promise

new Promise((resolve,reject)=>{
    console.log(1);
    //reject(2)
    resolve(2)
    console.log(3)
    setTimeout(()=>{console.log(4)},0)
}).then(res=>{
    console.log(res)
    return new Promise((resolve,reject)=>{
        resolve(5)
    }).then(res=>{
        return res
    })
}).then(res=>{
    console.log(res)
}).catch(e=>{
    console.log("e",e)
})
执行结果:
> 1
> 3
> 2
> 5
> 4
GitHub

wclimb

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97698.html

相关文章

  • JavaScript手写Promise

    摘要:如果状态是等待态的话,就往回调函数中函数,比如如下代码就会进入等待态的逻辑以上就是简单版实现实现一个符合规范的接下来大部分代码都是根据规范去实现的。 为更好的理解, 推荐阅读Promise/A+ 规范 实现一个简易版 Promise 在完成符合 Promise/A+ 规范的代码之前,我们可以先来实现一个简易版 Promise,因为在面试中,如果你能实现出一个简易版的 Promise ...

    stefan 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0
  • javascript异步Promise.all()、Promise.race()、Promise.

    摘要:的执行与状态无关当得到状态不论成功或失败后就会执行,原文链接参考链接对象 同期异步系列文章推荐谈一谈javascript异步javascript异步中的回调javascript异步与promisejavascript异步之Promise.resolve()、Promise.reject()javascript异步之Promise then和catchjavascript异步之async...

    clasnake 评论0 收藏0
  • javascript异步函数

    摘要:所以增加了异步函数,提高了代码可读性,对不太熟悉的人而言,帮助就更大了。因为异步函数去掉了所有回调。这就是此代码有效的原因它和以下一样代码更易读正如上面示例所见,与回调和代码相比,异步函数代码看起来非常简单。 这篇文章详细讲解了JavaScript中的异步函数。 JavaScript中的异步代码在很短的时间内从回调发展为Promise,再到ES2017的异步函数,现在我们可以像编写同步...

    WrBug 评论0 收藏0
  • Javascript基础-Promise

    摘要:转载自是什么呢根据的定义是一个被用于延时计算的最终结果的占位符这个怎么理解呢比如说,我要去麦当劳买点吃的,下单以后人家会先给你一个订单号,等人家外卖做好了,会提示你,并用那个订单小票来换取你真正的食物,在这时候,那个订单小票就是你这顿饭的 转载自: http://www.lht.ren/article/3/ Promise是什么呢?根据ecma-262的定义: Promise是一个被用...

    Carson 评论0 收藏0

发表评论

0条评论

zhaofeihao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<