簡體   English   中英

Javascript:Async/Await 內部有一個循環

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

在我的 react-native 中,我遇到了 async/await 函數的問題。 我需要從數據庫中獲取所有用戶並最終返回它。 但事情並沒有按正確的順序發生。

我很困惑我應該如何使用 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

我將采用“多步方法”,將基於回調的調用包裝到 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