国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

手寫一個符合promise/A+規(guī)范的promise庫

venmos / 3083人閱讀

摘要:使用及原理分析通過關(guān)鍵字創(chuàng)建實例接受一個參數(shù)方法返回兩個方法可用通過在方法中通過調(diào)用使成功或調(diào)用使失敗來控制狀態(tài)中可以執(zhí)行同步代碼也可以執(zhí)行異步代碼原型對象上有方法供實例調(diào)用方法接受兩個參數(shù)默認為一個函數(shù)默認為一個函數(shù)當狀態(tài)為時執(zhí)行用戶傳入

promise使用及原理分析:

通過new關(guān)鍵字創(chuàng)建promise實例, 接受一個executor參數(shù), executor方法返回兩個方法 resolve, reject, 可用通過在executor方法中通過調(diào)用resolve(使成功)或調(diào)用reject(使失敗),來控制promise狀態(tài)

let p = new Promise((resolve, reject) => {
    resolve(100)
})

executor中可以執(zhí)行同步代碼也可以執(zhí)行異步代碼

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(100)
    })
})

promise原型對象上有then方法供promise實例調(diào)用, then方法接受兩個參數(shù)onFulfilled, onRejected

onFulfilled默認為一個函數(shù) data => data

onRejected默認為一個函數(shù) err => {throw err}

當promise狀態(tài)為fulfilled時, 執(zhí)行用戶傳入的onFulfilled方法

當promise狀態(tài)為rejected時, 執(zhí)行用戶傳入的onRected方法

當用戶創(chuàng)建promise對象時采用異步,那么執(zhí)行then方法時沒有調(diào)用resolve方法或reject方法,所以promise狀態(tài)依然為pending狀態(tài),所以需要在then方法中采取發(fā)布訂閱模式,先保存then方法傳來的onFulfilled和onReje

又因為同一個promise實例可以調(diào)用多次then方法,從而傳多個onFulfilled和onRected,所以發(fā)布訂閱采用數(shù)組保存

onFulfilled和onRejected方法中可能throw Error, 所以在執(zhí)行onFulfilled和onRejected時需要try catch捕獲

then方法返回一個新的Promise實現(xiàn)鏈式編程

統(tǒng)一判斷then方法傳入的onFulfilled方法和onRejected方法中return的類型(resolvePromise)

p.then(data => {
    console.log(data)
}, err => {
    console.log(err)
})
let p1 = p.then(data => {
    return p1   // 報類型錯誤
})
p.then(data => {
    return new Promise((resolve, reject) => {
        resolve(100)
    })
})

catch方法接受一個錯誤回調(diào),可以用then方法實現(xiàn)(語法糖)

ES2018 中新增finally方法 也可以通過then方法實現(xiàn)(語法糖) finally要實現(xiàn)值得穿透, finally前如果有then方法,其返回值要穿過finally方法傳給之后的then

p.then(data => {
    return 100
}).finally(() => {
    console.log("finally")
}).then(data => {
    console.log(data)  // 100
})

all, race 方法都接受一個promise數(shù)組

all方法要所有promise都返回才resolve一個全部是成功態(tài)的數(shù)組,只要有一個rejected就直接reject

race方法只要有一個promise resolve就直接resolve

完整代碼如下:
class Promise {
    constructor(executor) {
        this.status = Promise.PENDING
        this.value = undefined
        this.reason = undefined
        // 發(fā)布訂閱的存儲器onResolvedCallbacks, onRejectedCallbacks
        this.onResolvedCallbacks = []
        this.onRejectedCallbacks = []
        this.initBind()
        this.init(executor)
    }
    initBind() {
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
    }
    init(executor) {
        // 防止executor中拋錯
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            this.reject(e)
        }
    }
    resolve(data) {
        // 如果resolve中傳入一個promise, 那么返回改promise結(jié)果
        if (data instanceof Promise) data.then(this.resolve, this.reject)
        if (this.status === Promise.PENDING) {
            this.status = Promise.FULFILLED
            this.value = data
            this.onResolvedCallbacks.forEach(fn => fn())
        }
    }
    reject(reason) {
        if (this.status === Promise.PENDING) {
            this.status = Promise.REJECTED
            this.reason = reason
            this.onRejectedCallbacks.forEach(fn => fn())
        }
    }
    then(onFulfilled, onRejected) {
        const fulfilledHandle = (resolve, reject) => {
            // 此處用setTimeout異步才能拿到promise2
            setTimeout(() => {
                try {
                    let x = onFulfilled(this.value)
                    Promise.resolvePromise(promise2, x, resolve, reject)
                } catch (e) {
                    reject(e)
                }
            })
        }
        const rejectHandle = (resolve, reject) => {
            setTimeout(() => {
                try {
                    let x = onRejected(this.reason)
                    Promise.resolvePromise(promise2, x, resolve, reject)
                } catch (e) {
                    reject(e)
                }
            })
        }
        // onFulfilled和onRejected定義默認值
        onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value
        onRejected = typeof onRejected === "function" ? onRejected : reason => {
            throw reason
        }
        let promise2 = new Promise((resolve, reject) => {
            if (this.status === Promise.FULFILLED) {
                fulfilledHandle(resolve, reject)
            }
            if (this.status === Promise.REJECTED) {
                rejectHandle(resolve, reject)
            }
            if (this.status === Promise.PENDING) {
                this.onResolvedCallbacks.push(() => {
                    fulfilledHandle(resolve, reject)
                })
                this.onRejectedCallbacks.push(() => {
                    rejectHandle(resolve, reject)
                })
            }
        })
        // 返回一個新的promise
        return promise2
    }
    catch (onRejected) {
        return this.then(null, onRejected)
    }
    static resolve() {
        return new Promise((resolve, reject) => {
            resolve()
        })
    }
    static reject() {
        return new Promise((resolve, reject) => {
            reject()
        })
    }
    finally(callback) {
        return this.then(
            data => Promise.resolve(callback()).then(() => data),
            err => Promise.resolve(callback()).then(() => {
                throw err
            })
        )
    }
    static all(promises) {
        return new Promise((resolve, reject) => {
            let result = []
            let count = 0
            const setResult = (key, value) => {
                result[key] = value
                if (++count === promises.length) {
                    resolve(result)
                }
            }
            for (let i = 0; i < promises.length; i++) {
                let current = promises[i]
                if (Promise.isPromise(current)) {
                    current.then(data => {
                        setResult(i, data)
                    }, reject)
                } else {
                    setResult(i, current)
                }
            }
        })
    }
    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                let current = promises[i]
                if (Promise.isPromise(current)) {
                    current.then(resolve, reject)
                } else {
                    resolve(current)
                }
            }
        })
    }
}
Promise.PENDING = "pending"
Promise.FULFILLED = "fulfilled"
Promise.REJECTED = "rejected"
Promise.resolvePromise = (promise2, x, resolve, reject) => {
    // called防止他人的promise即執(zhí)行resolve又執(zhí)行 reject
    let called
    if (promise2 === x) throw new TypeError("xxx")
    if (typeof x === "function" || typeof x === "object" && x !== null) {
        try {
            let then = x.then
            if (typeof then === "function") {
                then.call(x, y => {
                    if (called) return
                    called = true
                    // 遞歸解析,總有一個結(jié)果then方法返回一個普通值
                    Promise.resolvePromise(promise2, y, resolve, reject)
                }, e => {
                    if (called) return
                    called = true
                    reject(e)
                })
            } else {
                resolve(x)
            }
        } catch (e) {
            if (called) return
            called = true
            reject(e)
        }
    } else {
        resolve(x)
    }
}
Promise.isPromise = (obj) => {
    return typeof obj === "function" || typeof obj === "object" && obj !== null && obj.then && typeof obj.then === "function"
}
// 延遲對象
Promise.deferred = () => {
    const defer = {}
    defer.promise = new Promise((resolve, reject) => {
        defer.resolve = resolve
        defer.reject = reject
    })
    return defer
}

module.exports = Promise

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104774.html

相關(guān)文章

  • 手寫一個符合A+規(guī)范Promise

    摘要:本文同時也發(fā)布在我的博客上,歡迎之前也手寫過簡單的,這次則是為了通過官方的測試集,借鑒了一些下載量較多的,改了幾遍,終于是通過了規(guī)范的個測試用例如何測試測試庫地址在這,大家在寫完自己的后,不妨也去測試一下,檢驗自己的是否符合規(guī)范。 本文同時也發(fā)布在我的github博客上,歡迎star~ 之前也手寫過簡單的promise,這次則是為了通過官方的Promise A+測試集,借鑒了一些下載量...

    jsummer 評論0 收藏0
  • 手寫一款符合Promise/A+規(guī)范Promise

    摘要:手寫一款符合規(guī)范的長篇預(yù)警有點長,可以選擇性觀看。初始狀態(tài)是,狀態(tài)可以有或者不能從轉(zhuǎn)換為或者從轉(zhuǎn)換成即只要由狀態(tài)轉(zhuǎn)換為其他狀態(tài)后,狀態(tài)就不可變更。 手寫一款符合Promise/A+規(guī)范的Promise 長篇預(yù)警!有點長,可以選擇性觀看。如果對Promise源碼不是很清楚,還是推薦從頭看,相信你認真從頭看到尾,并且去實際操作了,肯定會有收獲的。主要是代碼部分有點多,不過好多都是重復(fù)的,不...

    rubyshen 評論0 收藏0
  • 一步一步實現(xiàn)一個符合PromiseA+規(guī)范Promise(1)

    摘要:今天我們來自己手寫一個符合規(guī)范的庫。是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理和更強大。我們可以看到,其實就是一個構(gòu)造函數(shù)。所以說我們的數(shù)組里存的是一個一個的的回調(diào)函數(shù),也就是一個一個。 今天我們來自己手寫一個符合PromiseA+規(guī)范的Promise庫。大家是不是很激動呢?? showImg(https://segmentfault.com/img/bV6t4Z?...

    joyvw 評論0 收藏0
  • promise/A+規(guī)范翻譯以及手寫實現(xiàn)

    摘要:如果實現(xiàn)滿足所有要求,則實現(xiàn)可能允許。本條款允許使用特定于實現(xiàn)的方法來采用已知一致承諾的狀態(tài)。接下來根據(jù)規(guī)范進行手寫實現(xiàn)注釋偷懶就將對應(yīng)的規(guī)范標注出來,其實基本上就是對著規(guī)范實現(xiàn)。 如果要手寫實現(xiàn)promise,那么先看看promise/A+規(guī)范,再來實現(xiàn),將會事半功倍。那么我先翻譯一下Promise/A+規(guī)范中的內(nèi)容。 術(shù)語 1.1 promise 是一個帶有符合此規(guī)范的the...

    LiuZh 評論0 收藏0
  • 異步發(fā)展流程 —— 手寫一個符合 Promise/A+ 規(guī)范 Promise

    摘要:構(gòu)造函數(shù)的實現(xiàn)我們在使用的時候其實是使用關(guān)鍵字創(chuàng)建了一個的實例,其實是一個類,即構(gòu)造函數(shù),下面來實現(xiàn)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018998456); 閱讀原文 概述 Promise 是 js 異步編程的一種解決方案,避免了 回調(diào)地獄 給編程帶來的麻煩,在 ES6 中成為了標準,這篇文章重點不是敘...

    UnixAgain 評論0 收藏0

發(fā)表評論

0條評論

venmos

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<