简体   繁体   English

Javascript:Async/Await 内部有一个循环

[英]Javascript : Async/Await with a loop inside

In my react-native i have a problem with async/await functions.在我的 react-native 中,我遇到了 async/await 函数的问题。 I need to get all users from database and finally return it.我需要从数据库中获取所有用户并最终返回它。 but things are not happening in correct order.但事情并没有按正确的顺序发生。

I'm confused how should i use async/await.我很困惑我应该如何使用 async/await。

is this the right usage of it?这是正确的用法吗? Any help is highly appreciated任何帮助都受到高度赞赏

 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);

Using SQLite for React-Native : https://github.com/andpor/react-native-sqlite-storage为 React-Native 使用 SQLite: https : //github.com/andpor/react-native-sqlite-storage

I would go with a "multi step approach" by wrapping the callback-based calls into promises in order to use the advantages of a synchronous call sequence in the main part of the async function and instead of using the loop I would go with map ping the rows to the desired data structure.我将采用“多步方法”,将基于回调的调用包装到 Promise 中,以便在async函数的主要部分中使用同步调用序列的优势,而不是使用循环,我将使用map ping行到所需的数据结构。

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;
};

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

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