【问题标题】:Javascript : Async/Await with a loop insideJavascript:异步/等待,里面有一个循环
【发布时间】:2017-02-19 21:48:11
【问题描述】:

在我的 react-native 中,我遇到了异步/等待函数的问题。 我需要从数据库中获取所有用户并最终返回它。但事情并没有按正确的顺序发生。

我很困惑我应该如何使用 async/await。

这是正确的用法吗?任何帮助都非常感谢

import React, {Component, PropTypes} from 'react';
import {
  ActivityIndicator,
  StyleSheet,
  Text,
  View,
  NetInfo,
  AlertIOS,
} from 'react-native';

var SQLite = require('react-native-sqlite-storage');
var Loading = require("./Loading");
var DeviceInfo = require('react-native-device-info');
import { Actions } from 'react-native-router-flux';
var LOADING = {};
var db = SQLite.openDatabase({name : "oc.db", location: 'default'});
import CodePush from "react-native-code-push";
import I18n from 'react-native-i18n';
import translations from './translations';
I18n.fallbacks = true;

export default class Grab extends Component{
  constructor(props) {
        super(props);
        this.state = {
            terms: '',
            isLoading: false,
            isConnected: null,
            coursesFetched: false,
            registerFetched: false,
        };
    }

  componentWillMount() {

    NetInfo.isConnected.fetch().then(isConnected => {
      this.setState({
        isConnected: isConnected
      });
    });

    NetInfo.isConnected.addEventListener(
      'change',
      isConnected => {
        this.setState({
          isConnected: isConnected
        });
        console.log('Grab: internet status is', this.state.isConnected);
        this.sync();
      }
    );

    this.GrabData();

  }

  toggleAllowRestart() {
    this.state.restartAllowed
      ? CodePush.disallowRestart()
      : CodePush.allowRestart();

    this.setState({ restartAllowed: !this.state.restartAllowed });
  }

  sync() {
    console.log("Grab: Running manual code push update");
  CodePush.sync(
    {
      installMode: CodePush.InstallMode.IMMEDIATE,
      updateDialog: false
    },
  );
}

async getUsers() {
    const tx = await (
        new Promise(resolve =>
            db.transaction(resolve)
        )
    );

    const users = await (
        new Promise((resolve, reject) =>
            tx.executeSql(["SELECT * FROM users"],[], (tx, results) => {
                const userList = results.rows
                        .map((row, index) => ({
                            userId: row.item(index).userId,
                            userName: row.item(index).userName,
                            userMail: row.item(index).userMail,
                            active: row.item(index).active,
                            firstName: row.item(index).firstName,
                            lastName: row.item(index).lastName,
                            accessToken: row.item(index).access_token,
                            host: row.item(index).host,
                        }));

                resolve(userList);
            })
        )
    );
    console.log('users to return:', users);
    return users;
};

  async getBookable(users){
    console.log('Exectuing function getBookable. received data:', users);
    let results = [];
    console.log(users.length, ' Users received');
    for(let n=0; n < users.length; n++){
      try {
        let host = users[n].host;
        let access_token = users[n].access_token;
        let userId = users[n].userId;
        let response = await fetch(host + 'event/my_events', {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'language': DeviceInfo.getDeviceLocale(),
            'Authorization': 'Bearer ' + access_token
          }
        });
        let responseData = await response.json();
        //// Get container details
        if(responseData.container.length > 0){
          for(let i=0; i < responseData.container.length; i++){
            let cnid = responseData.container[i].nid;
            let ctitle = responseData.container[i].title;
            results.push(
              "INSERT INTO containersC (userId, nid, title) VALUES ('" + userId + "','" + cnid + "', '" + ctitle + "')"
            );
            //// Get courses for each container
            for(let j=0; j < responseData.container[i].course.length; j++){
              let course_id = responseData.container[i].course[j].nid;
              let title = responseData.container[i].course[j].title;
              let cost = responseData.container[i].course[j].cost;
              let status = responseData.container[i].course[j].status;
              let period = responseData.container[i].course[j].period.time_sys;
              //// Get details for each course
              try {
                let resp = await fetch(host + 'event/course_detail/' + course_id, {
                  method: 'POST',
                  headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                    'language': DeviceInfo.getDeviceLocale(),
                    'Authorization': 'Bearer ' + access_token
                  }
                });
                let respData = await resp.json();

                let desc = respData.data.content[0].value;
                let capacity = respData.data.content[1].value;
                let image = respData.data.image;
                let status = respData.data.book;
                let cancel = respData.data.cancel;
                let cd = responseData.data.dates;

                results.push(
                  "INSERT INTO courses (userId, course_id, container_nid, title, cost, status, period, desc, capacity, image, cancel) VALUES ('" + userId + "','" + course_id + "', '" + cnid + "', '" + title + "', '" + cost + "', '" + status + "', '" + period + "', '" + desc + "', '" + capacity + "', '" + image + "', '" + cancel + "')"
                );

                //// Getting lecture dates for each course
                for(let a=0; a < cd.length; a++){
                  let sdate = cd[a].start_time.split(" ");
                  let edate = cd[a].end_time.split(" ");
                  results.push(
                    "INSERT INTO lectures (userId, course_id, title, start_time, end_time, start_date, end_date, room, teacher) VALUES ('" + userId + "','" + course_id + "', '" + cd[a].title + "', '" + sdate[1] + "', '" + edate[1] + "', '" + sdate[0] + "', '" + edate[0] + "', '" + cd[a].room + "', '" + cd[a].teacher + "')"
                  );
                }
                //// End getting lecture dates for courses
                return true;
              } catch(error) {
                console.error(error);
              }
              //// End getting details for courses
            }
            //// End getting courses for containers
          }
        }
        //// End getting container details
        return true;
      } catch(error) {
        console.error(error);
      }
    }
  }

  redirectUser(){
    Actions.tabbar({type: 'reset'});
  }

  async runQuery(query) {
    await db.transaction(tx => {
      return Promise.all(query.map(async (q) => {
        try {
          let results = await tx.executeSql(q, []);
          console.log('Query', q, 'Executed. results:', results);
        } catch(err) {
          console.log('Something went wrong while executing query', q, 'error is', err);
        }
      }));
    });
    return true;

  }

  async GrabData(){
    try {
      let users = await this.getUsers();
      //let [courses, register, evaluation] = await Promise.all([getBookable(users), getRegister(users), getEvaluation(users)]);
      let courses = await this.getBookable(users);
      //let query = [courses, register, evaluation];
      let query = [courses];
      await this.runQuery(["DELETE FROM containersC", "DELETE FROM courses", "DELETE FROM lectures", "DELETE FROM containersR", "DELETE FROM register", "DELETE FROM lectures", "DELETE FROM evaluations", "DELETE FROM fields"]);
      await this.runQuery(query);
      //this.redirectUser();
    } catch(error){
      console.log(error);
    }
  }


  render() {

return(
    <View style={styles.container}><Loading/></View>
  );
  }

}

var styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: "#fff",
      flexDirection: "column",
    },
});

Grab = CodePush(Grab);

在 React-Native 中使用 SQLite:https://github.com/andpor/react-native-sqlite-storage

【问题讨论】:

  • i have a problem with async/await functions - 是什么问题?
  • @JaromandaX 我无法正常工作。根本行不通。我需要从数据库中获取所有用户,然后返回它。
  • @JaromandaX 如果它是类中间的方法,则不会。
  • @JaromandaX 当我输入函数时,它会给出语法错误。异步函数 getUsers()

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


【解决方案1】:

我将采用“多步骤方法”,将基于回调的调用包装到 Promise 中,以便在 async 函数的主要部分使用同步调用序列的优势,而不是使用循环 I将使用mapping 行到所需的数据结构。

async getUsers() {
    const tx = await (
        new Promise(resolve =>
            db.transaction(resolve)
        )
    );

    const users = await (
        new Promise((resolve, reject) =>
            tx.executeSql(["SELECT * FROM users"], [], (tx, results) => {
                const item = results.rows.item;
                const count = item.length;

                const userList = Array.apply(null, Array(count))
                    .map((dummy, index) => {
                        const user = item(index);

                        return {
                            userId: user.userId,
                            userName: user.userName,
                            userMail: user.userMail,
                            active: user.active,
                            firstName: user.firstName,
                            lastName: user.lastName,
                            accessToken: user.access_token,
                            host: user.host,
                        };
                    });

                resolve(userList);
            })
        )
    );

    return users;
};

【讨论】:

  • 感谢您的回答。我只是简单地复制并粘贴它,但它在您使用 .reduce 的行中给出了语法错误,它可能是什么?
  • 澳大利亚。在reduce 之前缺少)
  • 我可以请您更新答案吗?我尝试添加它,仍然是同样的问题。
  • 我更新了答案,也摆脱了对象数据结构。相反,userList 现在是一个包含用户对象的数组。
  • 谢谢。我应该使用异步函数 getUsers 还是异步 getUsers?当我使用函数时,它会给出语法错误
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 2021-06-01
  • 2020-09-07
  • 2021-12-24
  • 1970-01-01
  • 2020-04-20
  • 2018-09-25
  • 1970-01-01
相关资源
最近更新 更多