【问题标题】:Cycle.js: Custom driver not emitting any event inside main()Cycle.js:自定义驱动程序在 main() 内不发出任何事件
【发布时间】:2020-06-17 04:47:14
【问题描述】:

我正在创建一个自定义cycle.js 驱动程序,用于预加载图像。主函数导出一个接收器流imagesToLoad,发出一组图像 URL。然后由驱动程序加载它们,并且应该返回一个在图像完成加载时发出的流。

问题

我可以在驱动程序代码中订阅驱动程序返回的流,并看到加载的图像确实被发出但从主函数内部映射时不会发出

我可能做错了什么,但我看不出到底是什么。

司机

import { from, Subject } from 'rxjs'
import { adapt } from '@cycle/run/lib/adapt'

const loadImage = (src) =>
    new Promise((resolve, reject) => {
        const img = new Image()
        img.addEventListener('load', () => resolve(img))
        img.addEventListener('error', (err) => reject(err))
        img.src = src
    })

export const makeImageLoaderDriver = () => {

    const imageLoaderDriver = (sink$) => {
        const imageCache = {}
        const source$ = new Subject()

        from(source$).subscribe({
            next(images) {
                const imagesPromises = images.map((src) => {
                    const imgSuccess = { src, loaded: true }
                    if (!!imageCache[src]) return Promise.resolve(imgSuccess)
                    return loadImage(src)
                        .then(() => {
                            imageCache[src] = imgSuccess
                        })
                        .catch((error) => {
                            imageCache[src] = { src, loaded: false, error }
                        })
                })

                Promise.all(imagesPromises).then(() => {
                    source$.next(imageCache)
                })
            },
        })

        return adapt(source$)
    }

    return imageLoaderDriver
}

index.js

const drivers = {
    imagesToLoad: makeImageLoaderDriver(),
}

run(main, drivers)

主要功能

export function main(sources) {

    sources.imagesToLoad.pipe(map(console.log)) // THIS NEVER LOGS ANYTHING

    return {
        imagesToLoad: of([ imageUrl1, imageUrl2 ]),
    }
}

【问题讨论】:

    标签: javascript cyclejs


    【解决方案1】:

    sources.imagesToLoad.pipe(map(console.log)) 创建了一个新的 Observable,但是这个 Observable 没有被命名(作为 const)并且没有在其他任何地方使用。它只是被删除并且从未订阅过,所以main 中的那一行实际上什么都不做。

    它需要插入到其他流管道中,这些管道会以某种方式最终进入 sink。例如,获取该操作的输出,将其命名为 const,然后在另一个流管道中使用该 const 流,并且该流管道最终必须在接收器中结束。

    要调试,您可以将.subscribe() 放在map 之后,您很可能会看到console.log 发生。只是不要在代码中留下 subscribe(),因为 Cycle.js 是一个框架,您不需要在 main 端订阅,因为订阅是为驱动程序端准备的。

    还请注意,您的驱动程序将sink$ 作为输入,但它从不使用它。您应该订阅sink$ 并根据其发射执行效果。

    【讨论】:

    • 对!就是这样!我知道我错过了什么。这个优化完全有道理!谢谢!关于未使用的sink$,这是一个错误,我调用from(source$)的部分应该是from(sink$)。也感谢您指出这个错误! ?
    • 除了我的问题。你认为这个驱动有意义吗?我应该将它作为 npm 包发布吗?
    • 我会回答我自己的问题哈哈:就是这样:npmjs.com/package/cycle-image-loading-driver
    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2013-04-08
    • 2016-09-22
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多