在React中进行API调用时异步和等待的问题

时间:2019-06-18 16:17:54

标签: javascript reactjs async-await es6-promise

如何使API调用正确?

这是我的React组件的一个示例:

class AdminForm extends Component {
    state = {
        winnersIds: [],
        didSelectWinners: false,
        emptyWinners: true,
    };

    selectRandomWinners = async () => {
        this.generateRandomWinners();
        const winnersIds = await this.getWinners();

        winnersIds && this.setState(
            {
                winnersIds,
                didSelectWinners: true,
                emptyWinners: false
            });
    };

    generateRandomWinners() {
        fetch('/api/generate_random_winners', {
            method: 'PATCH',
            headers: {
                'Content-type': 'application/json',
            },
            body: JSON.stringify({randomize: true, numberOfWinners: 5}),
        })
            .then(res => res.json());
    }

    getWinners() {
        return fetch('/api/winners')
            .then(res => res.json())
            .catch((err) => {
                new Array(0)
            });
    }

    // Empties out winnersIds array
    resetWinnersAPI() {
        fetch('/api/winners', {
            method: 'DELETE',
            headers: {
                'Content-type': 'application/json',
            },
            body: JSON.stringify({resetWinners: true}),
        })
            .then(res => res.json());
    };

    resetWinners = () => {
        this.resetWinnersAPI();

        //ANYTHING AFTER HERE DOESNT RUN ANYMORE

        this.setState({winnersIds: [], emptyWinners: true, didSelectWinners: false});
    };

    render() {
        const {handleReset} = this.props;
        const {didSelectWinners, winnersIds, emptyWinners} = this.state;

        return (
            <div className="admin-form">
                <div className="admin-form--column__left center-content">
                    <div className="d-flex flex-column">
                        <div className="p-2">
                            {
                                (emptyWinners && !didSelectWinners) ?
                                    <SelectRandomWinners selectRandomWinners={this.selectRandomWinners}/> :
                                    <Fragment>
                                        <ResetWinners resetWinners={this.resetWinners}/>
                                        <UserList winnersIds={winnersIds}/>
                                    </Fragment>
                            }
                        </div>
                        <div className="p-2">
                            <GoHomeButton home={handleReset}/>
                        </div>
                    </div>
                </div>
                <div className="admin-form--column__right"/>
            </div>
        )
    }
}

SelectRandomWinners组件:

class SelectRandomWinners extends React.Component {
    render() {
        const {selectRandomWinners} = this.props;

        return (
            <button
                className="ui black button"
                onClick={() => {
                    selectRandomWinners();
                }}
            >
                Select Random Winners
            </button>
        )
    }
}

在生成获奖者然后将获奖者重置为空数组时,这种方法很好用,但是第二次尝试生成获奖者时,这需要很长时间。我认为我的异步和等待状态已关闭。

这是我的server.js

const express = require('express');
const bodyParser = require('body-parser');

const app = express();
const port = 5000;

const jsonParser = bodyParser.json();
const participants = [
    {id: '111111', is_winner: false},
    {id: '222222', is_winner: false},
    {id: '333333', is_winner: false},
    {id: '444444', is_winner: false},
    {id: '555555', is_winner: false},
];

const winnersIds = [];

const setRandomWinners = (participants, numberOfWinners) => {
    while (winnersIds.length < numberOfWinners) {
        const randomParticipant = participants[Math.floor(Math.random() * participants.length)];

        if (!winnersIds.includes(randomParticipant.id)) {
            winnersIds.push(randomParticipant.id);
        }
    }
};

app.get('/api/participants', (req, res) => {
    res.json(participants);
});

app.get('/api/winners', (req, res) => {
    res.json(winnersIds);
});

app.delete('/api/winners', jsonParser, (req) => {
    const {resetWinners} = req.body;

    if (resetWinners) {
        while (winnersIds.length) {
            winnersIds.pop();
        }
    }
});

app.patch('/api/generate_random_winners', jsonParser, (req) => {
    const {randomize, numberOfWinners} = req.body;

    randomize && setRandomWinners(participants, numberOfWinners);
    console.log('generated random winners')
});


app.listen(port, () => `Server running on port ${port}`);

0 个答案:

没有答案