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

資訊專欄INFORMATION COLUMN

JavaScript異步編程:幫助弗利薩完成8次變身

avwu / 1514人閱讀

摘要:請(qǐng)幫助弗利薩完全變身成第形態(tài),擊敗賽亞人。而弗利薩只要在每次變身成功或者失敗時(shí)發(fā)出通知就行了。讓弗利薩在變身完成或失敗時(shí),通過(guò)這個(gè),告知所有收看該節(jié)目的觀眾他變身失敗,或者成功了。讓弗利薩開(kāi)始變身前往查看示例代碼

這邊文章試圖通過(guò)一個(gè)例子展示javascript異步編程的幾種寫法。
示例說(shuō)明

弗利薩必須要從第1形態(tài)過(guò)渡到第8形態(tài)才有可能擊敗賽亞人,每一次變身成下一形態(tài)需要1秒鐘,在這期間他可能會(huì)遭受到賽亞人的攻擊,如果在變身過(guò)程中受到傷害,他將被打回第一形態(tài)。請(qǐng)幫助弗利薩完全變身成第8形態(tài),擊敗賽亞人。

弗利薩的單例對(duì)象

開(kāi)始創(chuàng)建一個(gè)弗利薩

 const Frieza = (function () {
            var state = 1; //內(nèi)部變量,表示弗利薩的當(dāng)前形態(tài)
            return {
                chargingFlag: false, //表示弗利薩是否正在變身中
                damage: function () {  //20%幾率收到傷害
                    return Math.random() < 0.2;
                },
                stateReset: function () { //打回第一形態(tài)
                    state = 1;
                },
                getState: function () { //外部訪問(wèn)state的接口函數(shù)
                    return state;
                },
                change: function (callback) { //變身

                    if (this.chargingFlag === true) { 
                        throw new Error(`弗利薩還沒(méi)變身完畢呢`);
                    }
                    this.chargingFlag = true;
                    console.log(`弗利薩開(kāi)始進(jìn)行第${state + 1}形態(tài)變身`)
                    setTimeout(() => { //每一階段變身消耗1秒
                        if (this.damage()) {
                            this.stateReset();
                            this.chargingFlag = false;
                            callback("變身被悟空打斷啦!");
                            return;
                        }
                        state++;
                        this.chargingFlag = false;
                        callback(null, state);
                    }, 1000)
                }

            }
        })();

以上代碼用立即執(zhí)行函數(shù)創(chuàng)建了一個(gè)弗利薩

state為內(nèi)部變量,表示弗利薩當(dāng)前的形態(tài),初始為第一形態(tài),并且設(shè)置了一個(gè)接口(getState函數(shù))供外部了解弗利薩當(dāng)前的形態(tài)。

change函數(shù)實(shí)現(xiàn)了弗利薩的變身,必須等到一次變身完畢后才能再次變身,每一次變身需要1秒鐘。

在每一次變身完畢后會(huì)執(zhí)行回調(diào)函數(shù),我們規(guī)定回調(diào)函數(shù)有兩個(gè)參數(shù),第一個(gè)表示變身失敗,被打斷時(shí)應(yīng)當(dāng)傳入的參數(shù),第二個(gè)表示變身成功時(shí)應(yīng)當(dāng)傳入的參數(shù)。

接下來(lái)需要寫一些代碼來(lái)幫助弗利薩鍥而不舍的變身,直到他成功變身到第8形態(tài)。示例最終會(huì)按下圖的樣子在控制臺(tái)中呈現(xiàn)。

用Promise幫助弗利薩:
        function keepChange() {
            return new Promise((resolve, reject) => {
                Frieza.change((err, state) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(state);
                    }
                })
            })
        }
        function handelKeepChange() {
            keepChange().then((x) => {
             if(x !== 8){
                handelKeepChange();
             } else {
                 console.log("成功!")
             }
        }).catch(err => {
            console.log(err);
            handelKeepChange();
        })
        }
       handelKeepChange();

看上去已經(jīng)不錯(cuò)了,這已經(jīng)比直接在回調(diào)函數(shù)里面寫回調(diào)函數(shù)要好得多了,我們通過(guò)遞歸調(diào)用handelKeepChange,讓這條Promise鏈持續(xù)到第八次變身完畢。

用Promise + 生成器幫助弗利薩
 // generator + promise

        function* async() {
            while (Frieza.getState() !== 8) {
                yield keepChange();
            }
            console.log("成功!");
        }
        function keepChange() {
            return new Promise((resolve, reject) => {
                Frieza.change((err, state) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(state);
                    }
                })
            })
        }
        function handleAsync(asyncFn) {
            const ita = asyncFn();
            function handle(v) {
                if (!v.done) {
                    v.value.then(state => {
                        handle(ita.next(state));
                    }).catch(err => {
                        console.log(err);
                        handle(ita.next());
                    })
                }
            }
            handle(ita.next());
        }
        handleAsync(async);

 

這種用生成器+promise的寫法比純用promise的寫法要復(fù)雜一些,但是因?yàn)槔昧松善鞯奶匦裕沟梦覀冊(cè)趫?zhí)行具體的異步業(yè)務(wù)時(shí),可以寫的比較優(yōu)雅:

        function* async() {
            while (Frieza.getState() !== 8) {
                yield keepChange();
            }
            console.log("成功!");
        }

這種寫法比較有親和力,邏輯上比較清晰。它內(nèi)部的實(shí)現(xiàn)是通過(guò)一個(gè)handleAsync函數(shù)不斷地遞歸調(diào)用handle函數(shù),從而讓生成器能在一次Promis承諾實(shí)現(xiàn)后讓生成器繼續(xù)產(chǎn)出下一次Promise。

            function handle(v) {
                if (!v.done) { // 如果生成器還沒(méi)結(jié)束,那么就繼續(xù)產(chǎn)出一個(gè)promise
                    v.value.then(state => {
                        handle(ita.next(state));
                    }).catch(err => {
                        console.log(err);
                        handle(ita.next());
                    })
                }
            }
用async await幫助弗利薩

async await是promise+生成器的語(yǔ)法層面實(shí)現(xiàn)。可以讓我們省略背后的細(xì)節(jié),直接采用同步寫法編寫異步程序。

        async function handleAsync() {
            while(Frieza.getState() !== 8){
                try {
                    await keepChange();
                } catch (error) {
                    console.log(error)
                }
            }
            console.log("成功!");
           
        } 
        handleAsync(); */

這樣就可以了,幾乎與promise+與生成器的業(yè)務(wù)寫法一模一樣。

用rxjs幫助弗利薩

用上rxjs的觀察者模式后,實(shí)際上就可以把弗利薩的change函數(shù)里面的callback給解耦出來(lái)。把這部分的邏輯交給觀察者處理里面。而弗利薩只要在每次變身成功或者失敗時(shí)發(fā)出通知就行了。
具體步驟如下

創(chuàng)建一個(gè)可以供大家收看的電視節(jié)目"dragonBall",這個(gè)被我們叫做七龍珠的電視節(jié)目(subject)可以被觀眾們訂閱,同時(shí),這個(gè)電視節(jié)目也能隨心所欲的播放他想要給觀眾們看到的東西。

const dragonBall = new Rx.Subject();

讓弗利薩在變身完成或失敗時(shí),通過(guò)dragnonBall這個(gè)subject,告知所有收看該節(jié)目的觀眾他變身失敗,或者成功了。修改弗利薩的change函數(shù):

            change: function () {

                if (this.chargingFlag === true) {
                    drangonBall.next(new Error("變身還沒(méi)結(jié)束呢!"))
                }
                this.chargingFlag = true;
                console.log(`弗利薩開(kāi)始進(jìn)行第${state + 1}形態(tài)變身`)
                setTimeout(() => {
                    if (this.damage()) {
                        this.stateReset();
                        this.chargingFlag = false;
                        dragonBall.next(new Error("變身被悟空打斷啦!"));
                        return;
                    }
                    state++;
                    this.chargingFlag = false;
                    dragonBall.next(`${state}形態(tài)變身成功!`)
                }, 1000)
            }

收看dragonBall,并且在弗利薩沒(méi)變到第8形態(tài)前,持續(xù)地讓弗利薩變身。

        const watchAnime = dragonBall.asObservable()
        
        .subscribe(message => {
            console.log(message);
            
            if (Frieza.getState() !== 8) {
                Frieza.change();
            } else {
                watchAnime.unsubscribe();
            }

        })

讓弗利薩開(kāi)始變身

   Frieza.change();

前往github查看示例代碼

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

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

相關(guān)文章

  • JavaScript 編程精解 中文第三版 四、數(shù)據(jù)結(jié)構(gòu):對(duì)象和數(shù)組

    摘要:本章將介紹基本的數(shù)據(jù)結(jié)構(gòu)。松鼠人一般在晚上八點(diǎn)到十點(diǎn)之間,雅克就會(huì)變身成為一只毛茸茸的松鼠,尾巴上的毛十分濃密。我們將雅克的日記表示為對(duì)象數(shù)組。 來(lái)源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Data Structures: Objects and Arrays 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用谷歌翻譯 部分參考了《Jav...

    kamushin233 評(píng)論0 收藏0
  • 從云計(jì)算到邊緣計(jì)算 打造更智能的未來(lái)

    摘要:年月日,美國(guó),西雅圖微軟年度開(kāi)發(fā)者盛會(huì)在美國(guó)西雅圖開(kāi)幕,微軟公司首席執(zhí)行官薩提亞納德拉微軟全球執(zhí)行副總裁兼云計(jì)算與企業(yè)事業(yè)部負(fù)責(zé)人微軟全球執(zhí)行副總裁兼人工智能及微軟研究事業(yè)部負(fù)責(zé)人沈向洋,與數(shù)千名來(lái)自全球各地的開(kāi)發(fā)者齊聚一堂。2017年5月10日,美國(guó),西雅圖——微軟年度開(kāi)發(fā)者盛會(huì)Build 2017在美國(guó)西雅圖開(kāi)幕,微軟公司首席執(zhí)行官薩提亞 納德拉、微軟全球執(zhí)行副總裁兼云計(jì)算與企業(yè)事業(yè)部負(fù)...

    oneasp 評(píng)論0 收藏0
  • 搬瓦工,DC2(QN)機(jī)房CN2 VPS測(cè)評(píng),可選機(jī)房洛杉磯(QN,MC)/弗利蒙/新澤西/荷蘭

    摘要:瓦工的機(jī)房,電信為雙程線路,可選機(jī)房為洛杉磯弗利蒙新澤西荷蘭這個(gè)機(jī)房,帶寬為口,最低配的月流量為。相比較和價(jià)格相仿,但是配置更高,額外還贈(zèng)送免費(fèi)快照,免費(fèi)自動(dòng)備份等。瓦工的dc2機(jī)房,電信為雙程cn2線路,可選機(jī)房為洛杉磯(QN,MC)/弗利蒙/新澤西/荷蘭這5個(gè)機(jī)房,帶寬為G口,最低配的月流量為1T。相比較和dc3價(jià)格相仿,但是配置更高,額外還贈(zèng)送免費(fèi)快照,免費(fèi)自動(dòng)備份等。 ...

    miguel.jiang 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁(yè)面加載發(fā)生了什么這是一篇開(kāi)發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

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

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

0條評(píng)論

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