React-Native - 使用Promise

时间:2018-02-23 13:18:29

标签: javascript api react-native promise fetch

我正在将larger post分解为较小的问题。请理解我以前从未使用过Promise,而且我也是React-Native的新手。获得有关如何设置API调用和处理数据的反馈和建议会很棒。提前谢谢。

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

伪代码

  • 检索两个变量
  • 使用这两个变量构建网址
  • 触发第一个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>
        );
    }
};

1 个答案:

答案 0 :(得分: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>
        );
    }
};
  

我还没有检查回调函数上的错误,请注意使用此错误时会处理错误。