亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從零實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 Promise

kviccn / 3362人閱讀

摘要:本文參考了實(shí)踐教程實(shí)現(xiàn)這個(gè)視頻,并添加了自己的一些想法。三種狀態(tài)必須是函數(shù)初始狀態(tài)是返回值完成時(shí)調(diào)用的方法,這里做了容錯(cuò)拒絕時(shí)調(diào)用的方法再次運(yùn)行,正確打印出結(jié)果。

本文參考了Node.js 實(shí)踐教程 - Promise 實(shí)現(xiàn)這個(gè)視頻,并添加了自己的一些想法。

首先來(lái)看 Promise 的構(gòu)造:

// 這里用 Prometheus 代替 Promise
let p = new Prometheus((resolve, reject) => {
    resolve("hello")
})

下面我們來(lái)實(shí)現(xiàn)它:

// 三種狀態(tài)
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

function Prometheus (fn) {
    // fn 必須是函數(shù)
    if (typeof fn !== "function") {
        throw new Error("fn must be a function!")
    }

    let state = PENDING // 初始狀態(tài)是 PENDING
    let value = null // 返回值

    function fulfill (result) {
        state = FULFILLED
        value = result
    }

    // 完成時(shí)調(diào)用的方法,這里做了容錯(cuò)
    function resolve (result) {
        try {
            fulfill(result)
        } catch (err) {
            reject(err)
        }
    }

    // 拒絕時(shí)調(diào)用的方法
    function reject (error) {
        state = REJECTED
        value = error
    }

    fn(resolve, reject)
}

第二步,實(shí)現(xiàn) then 方法:

let p = new Prometheus((resolve, reject) => {
    resolve("hello")
})

p.then(val => {
    console.log(val)
})
// 三種狀態(tài)
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

function Prometheus (fn) {
    // fn 必須是函數(shù)
    if (typeof fn !== "function") {
        throw new Error("fn must be a function!")
    }

    let state = PENDING // 初始狀態(tài)是 PENDING
    let value = null // 返回值

    function fulfill (result) {
        state = FULFILLED
        value = result
    }

    // 完成時(shí)調(diào)用的方法,這里做了容錯(cuò)
    function resolve (result) {
        try {
            fulfill(result)
        } catch (err) {
            reject(err)
        }
    }

    // 拒絕時(shí)調(diào)用的方法
    function reject (error) {
        state = REJECTED
        value = error
    }

    this.then = function (onFulfill, onReject) {
        switch (state) {
            case FULFILLED:
                onFulfill(value)
                break
            case REJECTED:
                onReject(value)
                break
        }
    }

    fn(resolve, reject)
}

第三步,在 Promise 里使用異步

let p = new Prometheus((resolve, reject) => {
    setTimeout(() => {
        resolve("hello")
    }, 0)
})

p.then(val => {
    console.log(val)
})

直接運(yùn)行上面的代碼發(fā)現(xiàn)控制臺(tái)沒有打印出 hello,原因是 Prometheus 里的代碼是異步執(zhí)行,導(dǎo)致記下來(lái)執(zhí)行 then 方法的時(shí)候,statePENDING,后面再執(zhí)行 resolve 的時(shí)候就不會(huì)走到 onFulfill 了,所以我們要在 then 方法里添加 statePENDING 的分支判斷,把 onFulfillonReject 存到一個(gè)變量中:

// 三種狀態(tài)
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

function Prometheus (fn) {
    // fn 必須是函數(shù)
    if (typeof fn !== "function") {
        throw new Error("fn must be a function!")
    }

    let state = PENDING // 初始狀態(tài)是 PENDING
    let value = null // 返回值
    let hanler = {}

    function fulfill (result) {
        state = FULFILLED
        value = result
        handler.onFulfill(result)
    }

    // 完成時(shí)調(diào)用的方法,這里做了容錯(cuò)
    function resolve (result) {
        try {
            fulfill(result)
        } catch (err) {
            reject(err)
        }
    }

    // 拒絕時(shí)調(diào)用的方法
    function reject (error) {
        state = REJECTED
        value = error
        handler.onReject(error)
    }

    this.then = function (onFulfill, onReject) {
        switch (state) {
            case FULFILLED:
                onFulfill(value)
                break
            case REJECTED:
                onReject(value)
                break
            case PENDING:
                handler = { onFulfill, onReject }
        }
    }

    fn(resolve, reject)
}

異步實(shí)現(xiàn)了,我們?cè)倩剡^(guò)頭看看同步是否正常運(yùn)行:

let p = new Prometheus((resolve, reject) => {
  resolve("hello")
})

p.then(val => {
    console.log(val)
})

發(fā)現(xiàn)報(bào)錯(cuò)信息:

TypeError: handler.onReject is not a function

因?yàn)橥綀?zhí)行的時(shí)候,fulfillhandler{},所以會(huì)報(bào)錯(cuò)。

// 三種狀態(tài)
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

function Prometheus (fn) {
    // fn 必須是函數(shù)
    if (typeof fn !== "function") {
        throw new Error("fn must be a function!")
    }

    let state = PENDING // 初始狀態(tài)是 PENDING
    let value = null // 返回值
    let handler = {}

    function fulfill (result) {
        state = FULFILLED
        value = result
        next(handler)
    }

    // 完成時(shí)調(diào)用的方法,這里做了容錯(cuò)
    function resolve (result) {
        try {
            fulfill(result)
        } catch (err) {
            reject(err)
        }
    }

    // 拒絕時(shí)調(diào)用的方法
    function reject (error) {
        state = REJECTED
        value = error
        next(handler)
    }

    function next({ onFulfill, onReject }) {
        switch (state) {
            case FULFILLED:
                onFulfill && onFulfill(value)
                break
            case REJECTED:
                onReject && onReject(value)
                break
            case PENDING:
                handler = { onFulfill, onReject }
        }
    }

    this.then = function (onFulfill, onReject) {
        next({onFulfill, onReject})
    }

    fn(resolve, reject)
}

現(xiàn)在同步也可以正常運(yùn)行了,接下來(lái)看看多個(gè) then 鏈?zhǔn)秸{(diào)用:

let p = new Prometheus((resolve, reject) => {
  resolve("hello")
})

p.then(val => {
    console.log(val)
    return "world"
}).then(val => {
    console.log(val)
})

執(zhí)行代碼會(huì)發(fā)現(xiàn)如下報(bào)錯(cuò)信息:

TypeError: Cannot read property "then" of undefined

原因是 then 方法沒有返回 Promise。

// 三種狀態(tài)
const PENDING = Symbol()
const FULFILLED = Symbol()
const REJECTED = Symbol()

function Prometheus (fn) {
    // fn 必須是函數(shù)
    if (typeof fn !== "function") {
        throw new Error("fn must be a function!")
    }

    let state = PENDING // 初始狀態(tài)是 PENDING
    let value = null // 返回值
    let handler = {}

    function fulfill (result) {
        state = FULFILLED
        value = result
        next(handler)
    }

    // 完成時(shí)調(diào)用的方法,這里做了容錯(cuò)
    function resolve (result) {
        try {
            fulfill(result)
        } catch (err) {
            reject(err)
        }
    }

    // 拒絕時(shí)調(diào)用的方法
    function reject (error) {
        state = REJECTED
        value = error
        next(handler)
    }

    function next({ onFulfill, onReject }) {
        switch (state) {
            case FULFILLED:
                onFulfill && onFulfill(value)
                break
            case REJECTED:
                onReject && onReject(value)
                break
            case PENDING:
                handler = { onFulfill, onReject }
        }
    }

    this.then = function (onFulfill, onReject) {
        return new Prometheus((resolve, reject) => {
            next({
                onFulfill: val => {
                    resolve(onFulfill(val))
                },
                onReject: err => {
                    reject(onReject(err))
                }
            })
        })
    }

    fn(resolve, reject)
}

再次運(yùn)行,正確打印出結(jié)果。

到此,一個(gè)非常簡(jiǎn)單的 Promise 就實(shí)現(xiàn)了,當(dāng)然,這里其實(shí)還有很多細(xì)節(jié)沒有考慮,具體還要參考 Promise/A+。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84458.html

相關(guān)文章

  • 從零實(shí)現(xiàn)一個(gè)簡(jiǎn)易 Promise

    從零實(shí)現(xiàn)一個(gè)簡(jiǎn)易的 Promise 所有問(wèn)題都可以通過(guò)加一層中間層來(lái)解決。 Promises/A+ 簡(jiǎn)易的,不做廢話直接開始 :) const p = new Promise((resolve, reject)=>{ // 如果操作成功則調(diào)用 resolve 并傳入 value // 如果操作失敗則調(diào)用 reject 并傳入 reason }); 通常我們都會(huì)使用上述方法獲取 P...

    WilsonLiu95 評(píng)論0 收藏0
  • 從零開始實(shí)現(xiàn)一個(gè)自己Promise庫(kù)

    摘要:所以,這篇文章我會(huì)帶大家從零開始,手寫一個(gè)基本能用的。首先,規(guī)定對(duì)象是一個(gè)構(gòu)造函數(shù),用來(lái)生成實(shí)例。然后,這個(gè)構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù),該函數(shù)的兩個(gè)參數(shù)分別是和。對(duì)象通過(guò)自身的狀態(tài),來(lái)控制異步操作。 剛開始寫前端的時(shí)候,處理異步請(qǐng)求經(jīng)常用callback,簡(jiǎn)單又順手。后來(lái)寫著寫著就拋棄了callback,開始用promise來(lái)處理異步問(wèn)題。promise寫起來(lái)確實(shí)更加優(yōu)美,但由于缺乏...

    paulquei 評(píng)論0 收藏0
  • 從零開始寫一個(gè) Promise 庫(kù)

    摘要:是什么在規(guī)范中,是一個(gè)類,它的構(gòu)造函數(shù)接受一個(gè)函數(shù)。在這種情況下,是但處于狀態(tài)。與一起使用關(guān)鍵字會(huì)暫停執(zhí)行一個(gè)函數(shù),直到等待的變成狀態(tài)。此外,會(huì)一直等待調(diào)用直到下一個(gè)時(shí)序。 原文:Write Your Own Node.js Promise Library from Scratch作者:code_barbarian Promise 已經(jīng)是 JavaScript 中異步處理的基石,回調(diào)...

    Binguner 評(píng)論0 收藏0
  • 前端之從零開始系列

    摘要:只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙只有動(dòng)手,你才能真正掌握一門技術(shù)持續(xù)更新中項(xiàng)目地址求求求源碼系列跟一起學(xué)如何寫函數(shù)庫(kù)中高級(jí)前端面試手寫代碼無(wú)敵秘籍如何用不到行代碼寫一款屬于自己的類庫(kù)原理講解實(shí)現(xiàn)一個(gè)對(duì)象遵循規(guī)范實(shí)戰(zhàn)手摸手,帶你用擼 Do it yourself!!! 只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙 只有動(dòng)手,你才能真正掌握一門技術(shù) 持續(xù)更新中…… 項(xiàng)目地址 https...

    Youngdze 評(píng)論0 收藏0
  • 從零開始搭建React同構(gòu)應(yīng)用(四):搭建Koa Server & 完善SSR

    摘要:從零開始搭建同構(gòu)應(yīng)用四搭建完善上一篇我們使用了的方式測(cè)試了,這篇文章來(lái)講如何在前文的基礎(chǔ)上搭建一個(gè),實(shí)現(xiàn)真正意義上的。至此,一個(gè)簡(jiǎn)單的框架已經(jīng)搭建完成,剩下的工作就是結(jié)合工作需要,在里面添磚加瓦啦。 從零開始搭建React同構(gòu)應(yīng)用(四):搭建Koa Server & 完善SSR 上一篇我們使用了CLI的方式測(cè)試了SSR,這篇文章來(lái)講如何在前文的基礎(chǔ)上搭建一個(gè)Koa Server,實(shí)現(xiàn)真...

    fizz 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<