首页 > 解决方案 > 使用 apisauce 在 redux saga 中获取并发的多个 api 调用命中到后端服务器

问题描述

我们正在为我的应用程序使用ignite样板和apisuace。有一个奇怪的问题,其中一些 POST api 多次访问后端服务器,这会阻塞服务器并使服务器停机。有没有人遇到过这个问题?

后端服务器在一秒钟内获得超过 500 个并发请求。而且这种行为是间歇性的。

indexsaga.js

import { takeLatest, takeEvery } from "redux-saga/effects";
import API from "../Services/Api";
import FixtureAPI from "../Services/FixtureApi";
/* ------------- Types ------------- */
import { LoginTypes } from "../Redux/LoginRedux";


/* ------------- Sagas ------------- */

import {
    loginWithOther,
} from "./LoginSaga";

/* ------------- API ------------- */

// The API we use is only used from Sagas, so we create it here and pass along
// to the sagas which need it.
const api = DebugConfig.useFixtures ? FixtureAPI : API.create();

/* ------------- Connect Types To Sagas ------------- */

export default function* root() {
    yield [// some sagas receive extra parameters in addition to an action
        takeLatest(LoginTypes.USER_REQUEST, loginWithOther, api),
    ];
}

LoginSaga.js

import { call, put, all, fork, select } from "redux-saga/effects";
import LoginActions from "../Redux/LoginRedux";

export function* loginWithOther(api, action) {
    const { email, password, navigation } = action;
    let payload = {
        user_id: email,
        password: password,
    };
    const response = yield call(api.loginWithEmail, payload);
    if (response.ok) {
            yield put(LoginActions.userSuccess(response));
        } else {
            yield put(LoginActions.userFailure());
        }
    } else {
        yield put(LoginActions.userFailure());
    }
}

登录redux.js

import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'

/* ------------- Types and Action Creators ------------- */

const { Types, Creators } = createActions({
    userRequest: ['email', 'password'],
    userSuccess: ['data'],
    userFailure: null
})

export const LoginTypes = Types
export default Creators

/* ------------- Initial State ------------- */

export const INITIAL_STATE = Immutable({
    fetching: false,
    login_error: false,
    data:null
})

/* ------------- Reducers ------------- */


export const request = (state, action) => {
    return state.merge({ fetching: true, login_error: false })
}

export const success = (state, action) => {
    const { data } = action
    return state.merge({
        fetching: false,
        login_error: false,
        data: data
    })
}

export const userFailure = (state) =>
    state.merge({ fetching: false, login_error: true })



/* ------------- Hookup Reducers To Types ------------- */

export const reducer = createReducer(INITIAL_STATE, {

    [Types.USER_REQUEST]: request,
    [Types.USER_SUCCESS]: success,
    [Types.USER_FAILURE]: userFailure
})

api.js

// a library to wrap and simplify api calls
import apisauce from "apisauce";

const create = (baseURL = Config.API_URL) => {
    // ------
    // STEP 1
    // ------
    //
    // Create and configure an apisauce-based api object.
    //
    const api = apisauce.create({
        // base URL is read from the "constructor"
        baseURL,
        // here are some default headers
        headers: {
            "Cache-Control": "no-cache",
            "Transfer-Encoding": "chunked"
            // 'Content-Encoding': 'gzip'
        },
        // 10 second timeout...
        timeout: 20000
    });


    const URL_STRINGS = {
        LOGIN_WITH_OTHER_EMAIL: "/api/v1/login/email",
    }

    const loginWithEmail = obj => {
        return api.post(URL_STRINGS.LOGIN_WITH_OTHER_EMAIL, obj);
    };


    return {
        loginWithEmail,
    }
};

// let's return back our create method as the default.
export default {
    create
};

登录屏幕.js

import React, { Component } from 'react'
import LoginActions from '../Redux/LoginRedux'
class LoginScreen extends Component {

    render(){
        <View>
            <Text>Login</Text>
        </View>
    }

    onLoginClick(){
        this.props.loginWithEmail("exampleemail@example.com","123456")
Ï
    }
}

const mapStateToProps = (state) => {
    return {
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        loginWithEmail: (email, password) =>
            dispatch(LoginActions.userRequest(email, password))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)

标签: react-nativereduxaxiosredux-saga

解决方案


推荐阅读