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

資訊專欄INFORMATION COLUMN

從命令式到響應(yīng)式(七)

MorePainMoreGain / 676人閱讀

摘要:響應(yīng)式組件上節(jié)中錯誤的把添加到了中,實際中它返回的是一個,先調(diào)整過來。將這兩條流合并成一條請求流。利用上面實現(xiàn)的方法,可以很方便的拿到響應(yīng)流,即。由于不同于,請求和響應(yīng)一一對應(yīng)的很好,所以這里可能需要一定的條件來拿到請求對應(yīng)的響應(yīng)。

上回搭建了一個組件以及它所依賴的服務(wù)的基本結(jié)構(gòu),這節(jié)接著它繼續(xù)。另外從本節(jié)開始,統(tǒng)一采用rxjs6的風格,6和5在寫法上最大的不同就是棄用鏈式調(diào)用,而采用pipe的方法,當然也有一些其它的變更,請自行翻閱文檔。

響應(yīng)式組件

上節(jié)中錯誤的把generateRandomCode 添加到了 subscription中,實際中它返回的是一個Observable,先調(diào)整過來。

initialModel() {
        this.randomCode = this.auth.generateRandomCode(this.generateCode$);
}

刪除 launch方法中的 .add(this.auth.generateRandomCode(this.generateCode$));

服務(wù)代碼

驗證碼變更的邏輯有兩處,第一是程序設(shè)定好的時間周期到達后,第二是用戶點點擊時。我們的組件中已經(jīng)設(shè)置了一個subject來獲取用戶的輸入,并且已經(jīng)傳給了服務(wù),現(xiàn)在我們來完善服務(wù)中獲取驗證碼的邏輯,也就是那個generateRandomCode方法。

generateRandomCode(signal: Observable): Observable {
    // 每30秒向后臺獲取一次驗證碼
    const period = timer(0, 1000 * 30) // 第一個參數(shù)延遲時間,第二個參數(shù)間隔周期。
            .pipe(
                mapTo(true)
            );

    // 將這兩條流合并成一條請求流。
    const request = merge(signal, period);

    // 修改返回,當請求流中產(chǎn)生數(shù)據(jù)后,向服務(wù)器請求并將結(jié)果返回。
    return request.pipe(
        switchMapTo(this.http.get(url)),
        map((res: Response)) => {
            // 假設(shè)數(shù)據(jù)保存在random 字段下
            const body = res.json();

            return body.data.random;
        }
    )
}

隨便碼請求的過程就完成了,當然還可以添加其它邏輯,如限制用戶10秒內(nèi)最多可以獲取一次,可以給傳入的 signal 加 debounce time

const signal2 = signal.pipe(
    debounceTime(10 * 1000)
)

另外還有對于錯誤的處理等,可以參照之前 前端大耍 的那篇 《Angular Http 請求出錯后重試》。

既然說到了http的失敗重試,其實websocket也一樣。

websocket的響應(yīng)式

首先我們實現(xiàn)一個建議websocket連接的方法,代碼如下:

// url 和 protocols 不需要解釋; input: 請求數(shù)據(jù)的流,通過它來向服務(wù)端發(fā)送數(shù)據(jù)。
function connect(url, input, protocols) {

    const connectionStatus = new BehaviorSubject(0); // 用來查看當前連接的狀態(tài)。

    const messages = new Observable(function (observer) {
        
        const socket = new WebSocket(url, protocols);

        const inputSubscription;

        const open = false;

        const forcedClose = false;

        const closed = () => {
            if (!open) return;
            connectionStatus.next(connectionStatus.getValue() - 1);
            open = false;
        };

        socket.onopen = () => {
            open = true;
            connectionStatus.next(connectionStatus.getValue() + 1);
            inputSubscription = input.subscribe( data => socket.send(data));
        };

        socket.onmessage = message => observer.next(message.data);

        socket.onerror = error => {
            closed();
            observer.error(error);
        };

        socket.onclose = event => {
            closed();
            if (forcedClose)
                observer.complete();
            else
                observer.error(new Error(event.reason));
        };

        return function () {
            forcedClose = true;
            
            if (inputSubscription)
                inputSubscription.unsubscribe();
            if (open) {
                closed();
                socket.close();
            }
        };
    });

    return { messages: messages, connectionStatus: connectionStatus };
}

利用上面實現(xiàn)的方法,可以很方便的拿到響應(yīng)流,即 message。

@Injectable()
export class WebSocketService {
    inputStream: Subject = new Subject(); // 和上面寫好的方法進行通信

    message: Observable; // 暴露給調(diào)用者來獲取數(shù)據(jù)

    constructor() {
        this.connect()
    }

    // 暴露給其它服務(wù)或組件來發(fā)送數(shù)據(jù),同時獲得請求對應(yīng)的響應(yīng)。
    send(data) {
        this.inputStream.next(data);

        // 由于websocket 不同于http,請求和響應(yīng)一一對應(yīng)的很好,所以這里可能需要一定的條件來拿到請求對應(yīng)的響應(yīng)。
        return this.message.pipe(
            filter(message => message.flag === data.flag)
        );
    }

    private connect(): void {
        if(this.message) return;

        const { message, connectStatus } = connect(youUrl, this.inputSteam);

        this.message = message.pipe(
            map(response => /*處理數(shù)據(jù)邏輯*/),
            retryWhen(error => error.pipe(
                tap(err => console.log(err)),  // 打印一下錯誤,可以換成其它的邏輯。
                delay(500) // 500毫秒后發(fā)起重試
            )),
            share() // 將這個流變?yōu)閔ot,至于流的hot 和 cold可能需要多帶帶的文章來解釋。
        );

        connectStatus.subscribe(status => console.log("當前連接的狀態(tài):" + status))
    }
}

可以看出在響應(yīng)式的代碼中,很少需要維護一些中間數(shù)據(jù)狀態(tài),數(shù)據(jù)都是在流中獲取,轉(zhuǎn)換和傳遞,訂閱者對數(shù)據(jù)最好可以實現(xiàn)開箱即用,無需另外的加工。

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

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

相關(guān)文章

  • Spring Boot 2.x 系列教程:WebFlux 系列教程大綱(一)

    摘要:使用則需要及以上版本。開發(fā)使用框架七系列教程目錄系列教程大綱快速入門實踐實踐整合整合中和實踐整合中實現(xiàn)緩存中實現(xiàn)通信集成測試及部署實戰(zhàn)圖書管理系統(tǒng) WebFlux 系列教程大綱 一、背景 大家都知道,Spring Framework 是 Java/Spring 應(yīng)用程序跨平臺開發(fā)框架,也是 Java EE(Java Enterprise Edition) 輕量級框架,其 Spring ...

    jone5679 評論0 收藏0
  • 響應(yīng)設(shè)計個人的一些總結(jié)

    摘要:所以一個網(wǎng),甚至是響應(yīng)式設(shè)計,在兩個平臺上都會損害您整體的。三響應(yīng)式與如果把網(wǎng)站作為一個單獨的網(wǎng)站,如果網(wǎng)站的內(nèi)容與桌面版的內(nèi)容相對缺少,導(dǎo)致用戶回到桌面端的網(wǎng)站,會記錄這種選擇,使搜索排名降低,國內(nèi)百度就不知道會怎樣。 一、為什么需要響應(yīng)式設(shè)計(responsible web design) 1. 響應(yīng)式發(fā)展背景 1、屏幕尺寸的快速變化,iphone為320x480,分辨率在未來可以...

    LeoHsiun 評論0 收藏0
  • 命令響應(yīng)(一)

    摘要:響應(yīng)式命令式這兩種編程風格的思維方式是完全相反的。第二種方式是工人主動去找工人索取生產(chǎn)手機所要的零件,然后生產(chǎn)一臺完整的手機,這兩種方式就對應(yīng)的響應(yīng)式和命令式。 angular2中內(nèi)置了rxjs,雖然框架本身并沒有強制開發(fā)者使用響應(yīng)式風格來組織代碼,但是從框架開發(fā)團隊的角度可以看出他們必然是認同這種編程風格的。rxjs本質(zhì)是基于函數(shù)式編程的響應(yīng)式風格的庫,函數(shù)式相對于面向?qū)ο髞碚f更加抽...

    JayChen 評論0 收藏0
  • 【CuteJavaScript】Angular6入門項目(3.編寫服務(wù)和引入RxJS)

    摘要:發(fā)布通過回調(diào)方法向發(fā)布事件。觀察者一個回調(diào)函數(shù)的集合,它知道如何去監(jiān)聽由提供的值。 本文目錄 一、項目起步 二、編寫路由組件 三、編寫頁面組件 1.編寫單一組件 2.模擬數(shù)據(jù) 3.編寫主從組件 四、編寫服務(wù) 1.為什么需要服務(wù) 2.編寫服務(wù) 五、引入RxJS 1.關(guān)于RxJS 2.引入RxJS 3.改造數(shù)據(jù)獲取方式 六、改造組件 1.添...

    RebeccaZhong 評論0 收藏0

發(fā)表評論

0條評論

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