javascript - 使用 put inside 匿名函数回调

标签 javascript reactjs redux redux-saga

我正在实现 Pusher 进入我的 React+Redux Saga 应用程序,但我在某些回调中遇到了一些问题,我无法点击 put(...) 方法。在方法中使用 console.log(...) 等确实显示了,但我无法 put 我的应用程序状态。

我在异步/生成器函数的某些实现上可能是错误的,但我现在几乎卡住了。

我的代码说明什么不会触发:

import { takeLatest } from 'redux-saga'
import { call, put } from 'redux-saga/effects'

// Pusher actions
export const pusherConnecting = () => {
    return {
        type: ActionTypes.PUSHER_CONNECTING
    }
};

export const pusherConnectSucceeded = (client) => {
    return {
        type: ActionTypes.PUSHER_CONNECT_SUCCEEDED,
        client: client
    }
};

const pusherConnectFailed = (exception) => {
    return {
        type: ActionTypes.PUSHER_CONNECT_FAILED,
        message: exception
    }
};

// Pusher Saga
function * connectPusher(action) {
    try {
        const pusher = yield call(Api.connectPusher, action.directory, function(subscription) {
            subscription.bind(PUSHER_BIND_RELOAD, function() {
                location.reload(true);
            });

            subscription.bind(PUSHER_BIND_REQUEST_DATA, function(data) {
                if (data) {
                    put(updateDirectory(data));
                } else {
                    put(requestDirectory(action.directory.id));
                }
            });
        });

        pusher.connection.bind('connected', function() {
            put(pusherConnectSucceeded(pusher));
        });

        yield put(pusherConnecting());

    } catch (e) {
        yield put(pusherConnectFailed(e));
    }
}

export default function * pusherSaga() {
    yield * takeLatest(ActionTypes.DIRECTORY_FETCH_SUCCEEDED, connectPusher);
}



// My Api.ConnectPusher
export function * connectPusher(directory, subscription) {
    var pusher = new Pusher(PUSHER_KEY, {
        encrypted: true
    });

    var channels = ["test1", "test2"  ];

    for (var i = 0; i < channels.length; i++) {
        // Take each channel and callback with the subscription
        yield subscription(pusher.subscribe(channels[i]));
    }

    return pusher;
}

基于@Sebastien 的解决方案

yield put(yield onConnect(pusher));

function onConnect(pusher) {
    return new Promise((resolve, reject) => {
        pusher.connection.bind('connected', function() {
            resolve(pusherConnectSucceeded(pusher));
        });
    });
}

最佳答案

Redux-saga 不允许在不使用关键字yield 的情况下put。 put 创建一个必须解释/执行的简单 json 对象/效果,如果您不屈服,它就不会。

此外,即使使用 yield put(...),如果这是在回调中完成的,它也不会被解释,因为 Redux-saga 没有能力在回调中运行它的解释器。它们将作为正常回调运行,不会发生任何事情。

如果 subscription.bind 应该返回单个结果,您可以将该调用包装到返回 promise 的函数中,然后产生该 promise 。

如果 subscription.bind 应该返回结果流,您可能需要创建 channel 而不是.我猜将来有人会发布一些可以轻松允许将 Observables 转换为 Redux-saga 流的东西

请注意,如果您不需要多次取消订阅/重新订阅,将这段代码放在 saga 之外可能更简单

        subscription.bind(PUSHER_BIND_RELOAD, function() {
            location.reload(true);
        });

        subscription.bind(PUSHER_BIND_REQUEST_DATA, function(data) {
            if (data) {
                reduxStore.dispatch(updateDirectory(data));
            } else {
                reduxStore.dispatch((requestDirectory(action.directory.id));
            }
        });

关于javascript - 使用 put inside 匿名函数回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37724377/

相关文章:

javascript - 样式化 react 组件

javascript - JS打印函数,为什么返回false?

javascript - 有没有办法在 AngularJs 中使用两个 ng-apps,比如父应用程序和子应用程序?

javascript - React Canvas 上下文被写入到 componentDidMount 中

javascript - 尝试在 React/Redux/Jest 中测试调度操作函数时获取未定义的 .then

javascript - React Router 重新渲染路由而不是重新渲染组件

javascript - 将数据从部分获取到 Controller 的 Angular 方式是什么?

reactjs - 设置 vite --template React 和 eslint (airbnb)

javascript - React Js 有条件地应用类属性

javascript - 如何在 React Redux 应用程序中根据一个属性对数组进行排序,然后按另一个属性进行分组