简体   繁体   English

如何获取并保存异步函数的值

[英]How to get value of async function and save it

I'm new in javascript. 我是javascript新手。 I've a async function getListBar. 我有一个异步函数getListBar。 Inside getListBar i use return result of getAccount like a input of function fetch( you can see user.access_token) . 在getListBar内部,我使用getAccount的返回结果,就像函数fetch的输入一样(您可以看到user.access_token)。 Code run correct but i don't want call getAccount everytime i use getListBar. 代码运行正确,但是我不想每次使用getListBar时都调用getAccount。 So how can i get result of getAccount and save it ? 那么我如何获取getAccount的结果并保存呢?

I've tried many ways but promise very difficult to me , i don't know how to save result of it 我已经尝试了很多方法,但是对我来说非常困难,我不知道如何保存结果

async function getAccount() {
    try {
        let response = await fetch(apiAuthen,
            {
                method: 'POST',
                headers: {
                    Accept: '*/*',
                    'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'grant_type': 'password',
                },
                body: qs.stringify({
                    'grant_type': 'password',
                    'username': 'abc',
                    'password': 'abc',
                    'client_id': 'abc',
                })
            })
        let responseJson = await response.json();
        return responseJson.data;
    } catch (error) {
        console.log(`Error is : ${error}`);
    }
}
async function getListBar() {
    try {
        const user = await getAccount().then(user => { return user });
        let response = await fetch(apiBar,
            {
                headers: {
                    'Authorization': 'Bearer ' + user.access_token
                }
            })
        let responseJson = await response.json();
        return responseJson.data;
    } catch (error) {
        console.log(`Error is : ${error}`);
    }
}

getAccount will return a Promise like this and i want save access_token in it getAccount将返回这样的Promise,我想在其中保存access_token

Promise {_40: 0, _65: 0, _55: null, _72: null}
_40: 0
_55: {access_token: "41b369f2-c0d4-4190-8f3c-171dfb124844", token_type: "bearer", refresh_token: "55867bba-d728-40fd-bdb9-e8dcd971cb99", expires_in: 7673, scope: "read write"}
_65: 1
_72: null
__proto__: Object

If it is not possible to simply store a value in the same scope that these functions are defined, I would create a Service to handle getting the user. 如果不可能在定义这些函数的相同范围内简单地存储一个值,我将创建一个Service来处理获取用户的问题。 Preferably in its own file 最好在自己的文件中

AccountService.js AccountService.js

class AccountService {
  getAccount = async () => {
    if (this.user) {
      // if user has been stored in the past lets just return it right away
      return this.user;
    }
    try {
      const response = await fetch(apiAuthen, {
        method: 'POST',
        headers: {
          Accept: '*/*',
          Authorization: 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA==',
          'Content-Type': 'application/x-www-form-urlencoded',
          grant_type: 'password'
        },
        body: qs.stringify({
          grant_type: 'password',
          username: 'abc',
          password: 'abc',
          client_id: 'abc'
        })
      });

      const responseJson = await response.json();
      this.user = responseJson.data; // store the user
      return this.user;
    } catch (error) {
      console.log(`Error is : ${error}`);
    }
    // you should decide how to handle failures
    // return undefined;
    // throw Error('error getting user :(')
  };
}

// create a single instance of the class
export default new AccountService();

and import it where needed 并在需要的地方导入

import AccountService from './AccountService.js'

async function getListBar() {
    try {
        // use AccountService instead
        const user = await AccountService.getAccount().then(user => { return user });
        let response = await fetch(apiBar,
            {
                headers: {
                    'Authorization': 'Bearer ' + user.access_token
                }
            })
        let responseJson = await response.json();
        return responseJson.data;
    } catch (error) {
        console.log(`Error is : ${error}`);
    }
}

You will still be calling getAccount each time in getListBar but it will only fetch when AccountService has no user stored. 您仍然每次都会在getListBar中调用getAccount,但是只有在AccountService没有存储用户时,它才会获取。

Now i write in the different way 现在我用不同的方式写

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      accessToken: '',
      users: [],
      listBar: []
    }
  }
  //Get Account
  Check = () => {
    getAccount().then((users) => {
      this.setState({
        users: users,
        accessToken: users.access_token
      });
    }).catch((error) => {
      this.setState({ albumsFromServer: [] });
    });
  }

  //Get Account
  getAccount() {
    return fetch(apiAuthen,
      {
        method: 'POST',
        headers: {
          Accept: '*/*',
          'Authorization': 'Basic a2VwbGxheTpva2Vwba2VwbGxaQ1YWwjJA===',
          'Content-Type': 'application/x-www-form-urlencoded',
          'grant_type': 'password',
        },
        body: qs.stringify({
          'grant_type': 'password',
          'username': 'abc',
          'password': 'abc',
          'client_id': 'abc',
        })
      }).then((response) => response.json())
      .then((responseJson) => {
        this.setState({
          users: responseJson.data,
          accessToken: responseJson.data.access_token
        });
        return responseJson.data
      })
      .catch((error) => {
        console.error(error);
      });
  }
  //Get List Bar
  getListBarFromServer() {
    return fetch(apiBar, {
      headers: {
        'Authorization': 'Bearer ' + this.state.accessToken
      }
    }).then((response) => response.json())
      .then((responseJson) => {
        console.log(this.getListBarFromServer()) <---- Just run if console
        this.setState({ listBar: responseJson.data });
        return responseJson.data
      })
      .catch((error) => {
        console.error(error);
      });
  }
  componentDidMount() {
    this.getAccount();
    this.getListBarFromServer();
  }
  render() {
    return (
      <View style={{ top: 100 }}>
        <FlatList data={this.state.listBar} renderItem={({ item }) => {
          return (
            <View>
              <Text>{item.bar_id}</Text>
            </View>
          )
        }}>
        </FlatList>
      </View>
    )
  }
}

It's just run when i console.log(this.getListBarFromServer()) .Please explain to me why? 它只是在我console.log(this.getListBarFromServer())时运行。请向我解释为什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM