React-Native — 使用 Promise 为 API 请求构建动态 URL

问题描述 投票:0回答:1

我正在将较大的帖子分解为较小的问题。请理解我以前从未使用过 Promise,而且我也是 React-Native 的新手。如果能够获得有关如何设置 API 调用和处理数据的反馈和建议,那就太好了。

如何动态创建 API 请求的 URL?这就是我想要实现的目标:

伪代码

孩子

  • 检索两个变量
  • 使用这两个变量构建 URL
  • 触发第一个 Promise 并解决
  • 检索另外两个变量
  • 使用这两个变量构建一个新的 URL
  • 触发第二个Promise并解决
  • 从两个 Promise 收集数据并传递给父级

家长

  • 从 Child 检索数据
  • 从第一个 Promise 获取数据并设置为状态
  • 从第二个 Promise 获取数据并设置为另一个状态

APIservice.js

孩子

class APIservice {


    _getStopPoint = (endpoint) => {
        return new Promise(function(resolve, reject) {
            fetch(endpoint)
            .then((response) => response.json())
            .then((data) => {
                console.log("APIservice StopPoint", data)
                resolve(data);
            });
        });
    };
};


module.exports = new APIservice

List.js

家长

如您所见,我设置端点的方式很蹩脚。这并不理想,因为 URL 是相同的。我想构造一些可以接收两个变量并随时构建 URL 的东西。类似于

https://api.tfl.gov.uk/Line/${routeid}/Arrivals/${stationid}

如果我能做到这一点,如何将 API 调用传递给只有一个端点的 API 服务,该端点会根据接收到的两个变量动态变化?我不知道如何区分 Promise.all 中只有“一个”URL 的调用。

let APIservice = require('./APIservice')

let endpoint = 'https://api.tfl.gov.uk/Line/55/Arrivals/490004936E'
let endpoint1 = 'https://api.tfl.gov.uk/Line/Northern/Arrivals/940GZZLUODS'

export class List extends Component {
    constructor(props) {
        super(props);

        this.state = {
            bus: null,
            tube: null,
        }
    };

    componentWillMount() {
        let loadData = (endPoint) => {

            Promise.all([
                APIservice._getStopPoint(endpoint),
                APIservice._getStopPoint(endpoint1),
            ])
            .then((data) => {

                // Name for better identification
                const listBus = data[0]
                const listTube = data[1]

                this.setState({
                    bus: listBus,
                    tube: listTube
                }, () => {
                    console.log("bus", this.state.bus, "tube", this.state.tube)
                });
            })
            .catch((error) => {
                console.log(error)
            })
        }

        loadData(endpoint);
        loadData(endpoint1);

    }

    render() {
        return(
            <View>
                <FlatList 
                data={this.state.bus}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
                <FlatList 
                data={this.state.tube}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
            </ View>
        );
    }
};
javascript react-native promise
1个回答
1
投票

一旦您了解其工作原理,实现您所说的就非常容易了。

您正在使用

fetch
进行 API 调用,使用时会返回
Promise
。您的用例的伪代码将是这样的:

class APIService {
    static fetchFirst(cb) {
        fetch('FIRST_URL')
            .then(resp => {
                try {
                    resp = JSON.parse(resp._bodyText);
                    cb(resp);
                } catch(e) {
                    cb(e);
                }
            })
            .catch(e => cb(e));
    }

    static fetchSecond(routeid, stationid, cb) {
        fetch(`https://api.tfl.gov.uk/Line/${routeid}/Arrivals/${stationid}`)
            .then(resp => {
                try {
                    resp = JSON.parse(resp._bodyText);
                    cb(resp);
                } catch(e) {
                    cb(e);
                }
            })
            .catch(e => cb(e));
    }
}

module.exports = APIService;

将其包含在您的父组件中并按如下方式使用它:

let APIService = require('./APIService')

export class List extends Component {
    constructor(props) {
        super(props);

        this.state = {
            bus: null,
            tube: null,
        }
    };

    componentWillMount() {
        APIService.fetchFirst((resp1) => {
            APIService.fetchSecond(resp1.routeid, resp1.stationid, (resp2) => {
                this.setState({
                    tube: resp2
                });
            });
        });
    }

    render() {
        return(
            <View>
                <FlatList 
                data={this.state.bus}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
                <FlatList 
                data={this.state.tube}
                renderItem={({item}) => (
                    <Text>{item.timeToStation}</ Text>
                )}
                keyExtractor={item => item.id}
                />
            </ View>
        );
    }
};

我没有检查回调函数上的错误,请看你使用这个时错误的处理情况。

© www.soinside.com 2019 - 2024. All rights reserved.