将Promise中的值传递或访问API

时间:2016-08-19 16:44:19

标签: javascript asynchronous react-native promise es6-promise

我正在编写React Native应用程序,但我无法理解如何完成某项功能。基本上当用户登录时,我使用AsyncStorage将访问令牌的值保存到变量,但是我需要访问该变量以作为标题的一部分发送到API。

我正在使用getItem来访问存储,但它正在返回一个promise,我无法将其作为标题的一部分传递给它,因为它需要一个String。当我在console.log中返回时,它确实在控制台中显示为字符串。

所以主要问题是API期望一个字符串包含隐藏在Promise中的access_token,并且将Promise传递给API不起作用,因为我收到了错误请求错误。

以下是编辑用户页面的代码,getToken()和userUpdate()函数是问题所在。

'use strict'

import React, {Component} from 'react';
import {AsyncStorage, Text, View, TouchableHighlight} from 'react-native';
import {Actions, ActionConst} from 'react-native-router-flux';
import t from 'tcomb-form-native';
import _ from 'lodash';
import EStyleSheet from 'react-native-extended-stylesheet';

import GlobalStyles from '../styles/GlobalStyles';

import Global from '../components/Global';
import ViewContainer from '../components/ViewContainer';
import StatusBarBackground from '../components/StatusBarBackground';

let Form = t.form.Form;

var User = t.struct({
    email: t.String,
    firstName: t.String,
    lastName: t.String,
});

const options = {
    fields: {
        email: {
            autoCapitalize: 'none',
            autoCorrect: false,
            editable: false,
        },
        mobilePhone: {
            editable: false,
        }
    }
};

EStyleSheet.build(GlobalStyles);

class EditProfileScreen extends Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedTab: "EditProfileScreen",
            value: {
                email: Global.email,
                firstName: Global.firstName,
                lastName: Global.lastName
            }
        };
    }

    async _getToken(key) {
        AsyncStorage.getItem(key, (err, result) => {
            return result
        })
    }

    _userUpdate() {
        var value = this.refs.form.getValue();
        var access_token = this._getToken(Global.ACCESS_TOKEN)
        console.log(access_token)
        if (value) {
            fetch("https://test-integration.herokuapp.com/accounts/mine", {
                method: "PUT",
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${access_token}`
                },
                body: JSON.stringify({firstName: value.firstName, lastName: value.lastName})
            }).then((response) => response.json()).then((responseData) => {
                if (responseData) {
                    console.log(responseData)
                } else {
                    AlertIOS.alert("Login failed due to: " + responseData.message)
                }
            })
            .done()
        }
    }

    render() {
        return (
            <ViewContainer style={styles.viewContainer}>
                <Text style={styles.title}>
                    Edit Profile
                </Text>
                <View>
                    <Form ref="form" type={User} options={options} value={this.state.value} />
                </View>
                <View style={styles.row}>
                    <TouchableHighlight style={styles.button} onPress={this._userUpdate.bind(this)} underlayColor='#99d9f4'>
                        <Text style={styles.buttonText}>{_.capitalize('Confirm Edit')}</Text>
                    </TouchableHighlight>
                </View>
            </ViewContainer>
        );
    }
};

var styles = EStyleSheet.create({
    viewContainer: {
        justifyContent: 'center',
        padding: 20,
        backgroundColor: '$white',
    },

    title: {
        fontFamily: '$ralewayThin',
        color: '$primaryText',
        fontSize: 30,
        alignSelf: 'center',
        marginBottom: 30
    },

    buttonText: {
      fontFamily: '$ralewayRegular',
      fontSize: 18,
      color: '$white',
      alignSelf: 'center'
    },
    button: {
      height: 36,
      backgroundColor: '$primaryTeal',
      borderRadius: '$borderRadius',
      marginBottom: 10,
      marginLeft: 30,
      marginRight: 30,
      alignSelf: 'stretch',
      justifyContent: 'center'
    },

    row: {
        marginTop: 20
    }
});

module.exports = EditProfileScreen;

任何想法都将不胜感激!

1 个答案:

答案 0 :(得分:1)

如果您未通过_getToken返回承诺,则不必将await定义为异步函数。无论如何,首先你必须以一种或另一种方式回复承诺:

// async style
async _getToken(key) {
    return await AsyncStorage.getItem(key, (err, result) => {
        return result;
    });
}
// or old style
_getToken(key) {
    return AsyncStorage.getItem(key, (err, result) => {
        return result;
    });
}

但是当它到达_userUpdate时,异步函数真的派上用场了。您将其声明为async并await在执行函数的其余部分之前返回的令牌的值。

async _userUpdate() {
    var value = this.refs.form.getValue();
    var access_token = await this._getToken(Global.ACCESS_TOKEN)
    console.log(access_token)
    ...
}

这应该可以解决问题。

如果您想更好地了解async / await的工作原理,请查看此article