首页 > 解决方案 > Cycle.js:自定义驱动程序未在 main() 内发出任何事件

问题描述

我正在创建一个自定义cycle.js驱动程序,目的是预加载图像。main 函数导出一个接收器流,该接收器流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 ]),
    }
}

标签: javascriptcyclejs

解决方案


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

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

要进行调试,您可以将 放在.subscribe()之后map,并且很可能您会看到console.log发生的情况。只是不要将 留subscribe()在代码中,因为 Cycle.js 是一个框架,您不需要在其中订阅main,因为订阅是为驱动程序而设计的。

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


推荐阅读