成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【入門】promise的實(shí)現(xiàn)

ruicbAndroid / 3509人閱讀

摘要:狀態(tài)機(jī)由于僅僅是一個(gè)狀態(tài)機(jī),我們必須從我們將會(huì)用到的狀態(tài)信息開(kāi)始考慮。觀察方法我們現(xiàn)在有一個(gè)已經(jīng)完成的狀態(tài)機(jī),但是我們?nèi)匀粵](méi)有觀察他的變化。

promise javascript 異步

這幾天在看樸靈的深入淺出nodejs,看到異步編程的解決方案這一章時(shí),卡在了promise這個(gè)地方。心中的念頭就是自己動(dòng)手寫一個(gè)promise才好,于是就開(kāi)始在網(wǎng)上找資料。

簡(jiǎn)介,這些代碼首先是發(fā)表在Stack Overflow,是希望你能從中學(xué)習(xí)如何使用javascript實(shí)現(xiàn)一個(gè)promise,你將會(huì)更好的理解promise是如何的實(shí)現(xiàn)的。

狀態(tài)機(jī)

由于promise僅僅是一個(gè)狀態(tài)機(jī),我們必須從我們將會(huì)用到的狀態(tài)信息開(kāi)始考慮。

var PENDDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(){
    //保存的狀態(tài)可以為PENDDING,FULFILLED和REJECTED
    var state = PENDDING;
    //一旦FULFILLED或者REJECTED保存為value或者err
    var value = null;
    //保存成功或者失敗的處理程序
    var handlers = []
}
轉(zhuǎn)變

第二步,讓我們考慮下面兩種可能出現(xiàn)的情形,fulfilling和rejecting:

var PENDDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(){
    //保存的狀態(tài)可以為PENDDING,FULFILLED和REJECTED
    var state = PENDDING;
    //一旦FULFILLED或者REJECTED保存為value或者err
    var value = null;
    //保存成功或者失敗的處理程序
    var handlers = []

    function fullfill(result){
        state = FULFILLED;
        value = result;
    }

    function reject(error){
        state = REJECTED;
        value = error;
    }
}

上面這些給了我們較低等級(jí)的變換,但是我們還可以考慮額外更高級(jí)的叫做resolve的變換。

var PENDDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(){
    //保存的狀態(tài)可以為PENDDING,FULFILLED和REJECTED
    var state = PENDDING;
    //一旦FULFILLED或者REJECTED保存為value或者err
    var value = null;
    //保存成功或者失敗的處理程序
    var handlers = []

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

    function reject(error){
        state = REJECTED;
        value = error;
    }

    function resolve(result){
        try{
            var then = getThen(result);
            if(then){
                doResolve(then.resolve(result),resolve,reject)
                return 
            }
            fullfill(result)
        }catch(e){
            reject(e)
        }
    }
}

注意無(wú)論傳入resolve的是一個(gè)promise對(duì)象還是一個(gè)普通值,如果它是一個(gè)promise對(duì)象,等待他完成。一個(gè)promise對(duì)象不會(huì)進(jìn)入fulfilled狀態(tài)如果它還包含一個(gè)promise對(duì)象的話,因此我們將要暴露出的resolve函數(shù)強(qiáng)于內(nèi)部的fulfill。我們用到了一系列的輔助函數(shù),如下:

/**
 * 檢查一個(gè)value是否是一個(gè)promise對(duì)象,如果是,返回那個(gè)promise的then方法
 *
 * @param {promise|any} value
 * @return {Function|null}
 */
function getThen(value){
    var t = typeof value;
    if(value && (t === "object"||t === "function")){
        var then = value.then;
        if(typeof then === "function"){
            return then
        }
    }
    return null
}
/**
 * 創(chuàng)建一個(gè)對(duì)潛在行為的處理方法并且保證onFulfilled和onRejected只被調(diào)用一次
 * 不對(duì)異步做保證
 *
 * @param {Function} fn A resolver function that may not be trusted
 * @param {Function} onFulfilled
 * @param {Function} onRejected
 */
function doResolve(fn,onFulfilled,onRejected){
    var done = false;
    try{
        fn(function(value){
            if(done) return
            done = true
            onFulfilled(value)
        },function(reason){
            if(done) return 
            done = true
            onRejected(reason)
        })
    }catch(ex){
        if(done) return 
        done = true
        onRejected(ex)
    }
}

構(gòu)造

我們現(xiàn)在已經(jīng)完成了內(nèi)部的狀態(tài)機(jī),但同時(shí)我們還需要暴露一個(gè)處理或者觀察該promise的方法,我們來(lái)增加一個(gè)處理promise的途徑:

var PENDDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(fn){
    //保存的狀態(tài)可以為PENDDING,FULFILLED和REJECTED
    var state = PENDDING;
    //一旦FULFILLED或者REJECTED保存為value或者err
    var value = null;
    //保存成功或者失敗的處理程序
    var handlers = []


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

    function reject(error){
        state = REJECTED;
        value = error;
    }

    function resolve(result){
        try{
            var then = getThen(result);
            if(then){
                doResolve(then.resolve(result),resolve,reject)
                return 
            }
            fullfill(result)
        }catch(e){
            reject(e)
        }
    }

    doResolve(fn,resolve,reject)
}

如你所見(jiàn),我們復(fù)用了deResolve因?yàn)槲覀冇辛硪粋€(gè)不被信任的處理器,fn函數(shù)可以調(diào)用resolvereject多次,甚至可以拋出異常,我們現(xiàn)在要做的是保證promise只執(zhí)行或者拒絕一次,然后不在變換為其他的狀態(tài)。

觀察(.done方法)

我們現(xiàn)在有一個(gè)已經(jīng)完成的狀態(tài)機(jī),但是我們?nèi)匀粵](méi)有觀察他的變化。我們最終要完成的是實(shí)現(xiàn).then,但是由于.done簡(jiǎn)單很多于是我們就先實(shí)現(xiàn)它。
我們現(xiàn)在要實(shí)現(xiàn)promise.done(onFulfilled,onRejected)要滿足以下的功能:
- onFulfilledonRejected中一個(gè)被調(diào)用
- 只被調(diào)用一次
- 在下一個(gè)tick(即.done方法返回后)時(shí)才被調(diào)用
- 它將會(huì)被調(diào)用不管promise是在我們調(diào)用.done之前或者之后被處理

var PENDDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise(fn){
    //保存的狀態(tài)可以為PENDDING,FULFILLED和REJECTED
    var state = PENDDING;
    //一旦FULFILLED或者REJECTED保存為value或者err
    var value = null;
    //保存成功或者失敗的處理程序
    var handlers = []


    function fulfill(result){
        state = FULFILLED;
        value = result;
        handlers.forEach(handle);
        handlers = null
    }

    function reject(error){
        state = REJECTED;
        value = error;
        handlers.forEach(handle);
        handlers = null
    }

    function resolve(result){
        try{
            var then = getThen(result);
            if(then){
                doResolve(then.resolve(result),resolve,reject)
                return 
            }
            fullfill(result)
        }catch(e){
            reject(e)
        }
    }

    function handle(handler){
        if(state === PENDDING){
            handlers.push(handler)
        }else{
            if(state === FULFULLIED && typeof handler.onFulfilled === "function"){
                handler.onFulfilled(value);
            }
            if(state === REJECTED && typeof handler.onRejected === "function"){
                handler.onRejected(value);
            }
        }
    }

    this.done = function(onFulfilled,onRejected){
        //保證異步執(zhí)行
        setTimeout(function(){
            handle({
                onFulfilled : onFulfilled,
                onRejected  : onRejected
            })
        },0)
    }

    doResolve(fn,resolve,reject)
}

我們得確定Promise被Resolved或者Rejected后處理程序可以得到通知,僅僅是在進(jìn)入下一個(gè)tick時(shí)做這些。

觀察(.then方法)

現(xiàn)在我們已經(jīng)完成了.done方法,我們可以很類似的實(shí)現(xiàn).then方法,只是要多構(gòu)建一個(gè)Promise方法。

this.then = function(onFulfilled,onRejected){
    var self = this;
    return new Promise(function(resolve,Reject){
        return self.done(function(resolve){
                if(typeof onFulfilled === "function"){
                    try{
                        resolve(onFulfilled(result))
                    }catch(e){
                        reject(e)
                    }
                }else{
                    return resolve(result)
                }
        },function(error){
            if(typeof onRejected === "function"){
                try{
                    reject(onRejected(error))
                }catch(e){
                    reject(e)
                }
            }else{
                reject(error)
            }
        })
    })
}

以上翻譯自Promise Implementing。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/85417.html

相關(guān)文章

  • js異步從入門到放棄(實(shí)踐篇) — 常見(jiàn)寫法&面試題解析

    摘要:前文該系列下的前幾篇文章分別對(duì)不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場(chǎng)景和一些常見(jiàn)的面試題。流程調(diào)度里比較常見(jiàn)的一種錯(cuò)誤是看似串行的寫法,可以感受一下這個(gè)例子判斷以下幾種寫法的輸出結(jié)果辨別輸出順序這類題目一般出現(xiàn)在面試題里。 前文 該系列下的前幾篇文章分別對(duì)不同的幾種異步方案原理進(jìn)行解析,本文將介紹一些實(shí)際場(chǎng)景和一些常見(jiàn)的面試題。(積累不太夠,后面想到再補(bǔ)) 正文 流程調(diào)度...

    Awbeci 評(píng)論0 收藏0
  • 在非阻塞IO下nodejs下同步并行 ES6 promise入門深入(二)

    摘要:現(xiàn)在我們要用的重點(diǎn)就是我們的,這是一個(gè)能讓函數(shù)并行的,可以基于多個(gè)。非常有用啊先上一個(gè)錯(cuò)誤的代碼這時(shí)候我們得到的就是數(shù)字了,而不是一個(gè)數(shù)組,這就是神奇所在。 看過(guò) (一)的同學(xué)一定覺(jué)得這個(gè)Promise很簡(jiǎn)單,好像沒(méi)什么可以用的地方,但是事實(shí)上,它的用處非常大啊,尤其是在nodejs上,愈加重要,雖然已經(jīng)有大量的庫(kù)實(shí)現(xiàn)了對(duì)Promise的封裝了,不過(guò)我還是更傾向用原生的node來(lái)實(shí)現(xiàn)對(duì)...

    Jrain 評(píng)論0 收藏0
  • 在非阻塞IO下nodejs下同步并行 ES6 promise入門深入(二)

    摘要:現(xiàn)在我們要用的重點(diǎn)就是我們的,這是一個(gè)能讓函數(shù)并行的,可以基于多個(gè)。非常有用啊先上一個(gè)錯(cuò)誤的代碼這時(shí)候我們得到的就是數(shù)字了,而不是一個(gè)數(shù)組,這就是神奇所在。 看過(guò) (一)的同學(xué)一定覺(jué)得這個(gè)Promise很簡(jiǎn)單,好像沒(méi)什么可以用的地方,但是事實(shí)上,它的用處非常大啊,尤其是在nodejs上,愈加重要,雖然已經(jīng)有大量的庫(kù)實(shí)現(xiàn)了對(duì)Promise的封裝了,不過(guò)我還是更傾向用原生的node來(lái)實(shí)現(xiàn)對(duì)...

    verano 評(píng)論0 收藏0
  • Promise入門之基本用法

    摘要:入門之基本用法背景在我們使用異步函數(shù)比如進(jìn)行編寫代碼,如果我們需要很多個(gè)請(qǐng)求不同的接口,而下一個(gè)接口需要依賴上一個(gè)接口的返回值,這樣,我們的代碼則需要在各種回調(diào)函數(shù)中嵌套,這樣一層一層地下去,就形成了回調(diào)地獄。 Promise入門之基本用法 背景 在我們使用異步函數(shù)比如ajax進(jìn)行編寫代碼,如果我們需要很多個(gè)ajax請(qǐng)求不同的接口,而下一個(gè)接口需要依賴上一個(gè)接口的返回值,這樣,我們的代...

    siberiawolf 評(píng)論0 收藏0
  • Promise快速入門

    摘要:周五就想寫這篇文章,但是無(wú)奈花花世界的誘惑太多就一直拖到了今天,自責(zé)遍進(jìn)入正題對(duì)象用于表示一個(gè)異步操作的最終狀態(tài)完成或失敗,以及其返回的值。 周五就想寫這篇文章,但是無(wú)奈花花世界的誘惑太多……就一直拖到了今天,自責(zé)1e4遍;進(jìn)入正題Promise: Promise 對(duì)象用于表示一個(gè)異步操作的最終狀態(tài)(完成或失?。?,以及其返回的值。 上為MDNPromise的定義;ES6規(guī)定Promis...

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

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

0條評(píng)論

閱讀需要支付1元查看
<