将 Promise 中的值传递或访问到 API

Passing or accessing a value in Promise to API

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

我正在使用 getItem 来访问存储,但它是 return 一个承诺,我不能真正将其作为 header 的一部分传递,因为它需要一个字符串。但是,当我 console.log return 时,它确实在控制台中显示为字符串。

所以主要的问题是 API 期待一个包含 access_token 的字符串,它被埋在 Promise 中,并且将 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;

如有任何想法,我们将不胜感激!

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

// 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,异步函数就真的派上用场了。您将其声明为异步,并且 await 在执行函数的其余部分之前 return 编辑令牌的值。

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

这应该可以解决问题。

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