Giter Club home page Giter Club logo

Comments (4)

github-actions avatar github-actions commented on May 28, 2024

Thank feedback. We will check it later:-)

from remesh.

Lucifier129 avatar Lucifier129 commented on May 28, 2024

可以将 downloader 封装成 rxjsObservable 内部管理 cancel 逻辑.

大概像下面这样处理:

import { Observable, takeUntil, switchMap } from 'rxjs'

type DownloadState = {
    type: 'progress'
    progress: number
} | {
    type: 'error'
    error: string
} | {
    type: 'success'
    file: Blob
}

const download = (url: string) => {
    return new Observable<DownloadState>(subscriber => {
        const downloadId = downloader.startDownload(url, {
            onProgress: (progress) => {
                subscriber.next({ type: 'progress', progress })
            },
            onFinish: (file: Blob) => {
                subscriber.next({ type: 'success', file })
                subscriber.complete()
            },
            onFailed: (message: string) => {
                subscriber.next({ type: 'error', error: message })
                subscriber.complete()
            },
        })

        const unsubscribe = () => {
            downloader.cancelDownload(downloadId)
        }

        return unsubscribe
    })
}


domain.effect({
    name: 'DownloadEffect',
    impl: ({ fromEvent }) => {
        return fromEvent(DownloadStartedEvent).pipe(
            switchMap(event => {
                // cancel download if user cancels it
                return download(event.url).pipe(
                    takeUntil(fromEvent(DownloadCancelledEvent)),
                )
            }),
            map(state => {
                switch (state.type) {
                    case 'progress':
                        return DownloadProgressEvent(state.progress)
                    case 'error':
                        return DownloadFailedEvent(state.error)
                    case 'success':
                        return DownloadFinishedEvent(state.file)
                }
            })
        )
    }
})

from remesh.

ScarboroughCoral avatar ScarboroughCoral commented on May 28, 2024

可以将 downloader 封装成 rxjsObservable 内部管理 cancel 逻辑.

大概像下面这样处理:

import { Observable, takeUntil, switchMap } from 'rxjs'

type DownloadState = {
    type: 'progress'
    progress: number
} | {
    type: 'error'
    error: string
} | {
    type: 'success'
    file: Blob
}

const download = (url: string) => {
    return new Observable<DownloadState>(subscriber => {
        const downloadId = downloader.startDownload(url, {
            onProgress: (progress) => {
                subscriber.next({ type: 'progress', progress })
            },
            onFinish: (file: Blob) => {
                subscriber.next({ type: 'success', file })
                subscriber.complete()
            },
            onFailed: (message: string) => {
                subscriber.next({ type: 'error', error: message })
                subscriber.complete()
            },
        })

        const unsubscribe = () => {
            downloader.cancelDownload(downloadId)
        }

        return unsubscribe
    })
}


domain.effect({
    name: 'DownloadEffect',
    impl: ({ fromEvent }) => {
        return fromEvent(DownloadStartedEvent).pipe(
            switchMap(event => {
                // cancel download if user cancels it
                return download(event.url).pipe(
                    takeUntil(fromEvent(DownloadCancelledEvent)),
                )
            }),
            map(state => {
                switch (state.type) {
                    case 'progress':
                        return DownloadProgressEvent(state.progress)
                    case 'error':
                        return DownloadFailedEvent(state.error)
                    case 'success':
                        return DownloadFinishedEvent(state.file)
                }
            })
        )
    }
})

感谢! 太优雅了!

from remesh.

Lucifier129 avatar Lucifier129 commented on May 28, 2024

如果要支持同时下载很多个,可以将 switchMap 替换成 mergeMap,并且根据 DownloadCancelledEvent 携带的 url 进行过滤。以及拓展 DownloadState使之携带 url等数据

大概像下面这样:

domain.effect({
    name: 'DownloadEffect',
    impl: ({ fromEvent }) => {
        return fromEvent(DownloadStartedEvent).pipe(
            // for each download event, create a stream of progress events
            // merge them together instead of switching
            mergeMap(event => {
                // create a stream of cancel events for this download
                const cancel$ = fromEvent(DownloadCancelledEvent).pipe(
                    filter(cancelledEvent => cancelledEvent.url === event.url)
                )
                // cancel download if user cancels it
                return download(event.url).pipe(takeUntil(cancel$))
            }),
            map(state => {
                switch (state.type) {
                    case 'progress':
                        return DownloadProgressEvent(state)
                    case 'error':
                        return DownloadFailedEvent(state)
                    case 'success':
                        return DownloadFinishedEvent(state)
                }
            })
        )
    }
})

from remesh.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.