Reagieren Native: synchron ausführen von Funktionen
Ich bin neu in der OOP. Meines Wissens Versprechungen/asynchron/synchron Laufenden Funktionen ist einfach basic. Ich würde wirklich zu schätzen Ihre Zeit und Aufmerksamkeit!
Dies ist am Beispiel von Reaktion-Native docs:
JS:
async function getMoviesFromApi() {
try {
let response = await fetch('https://facebook.github.io/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch(error) {
console.error(error);
}
}
So wie ich das verstehe aus dem code oben, getMoviesFromApi ist deklariert als async-Funktion. das heißt, es wird Funktionen ausführen einer nach dem anderen. Richtig? bitte korrigieren Sie mich, wenn nicht!
wird es erstmal warten mit abrufen zu beenden, dann rufen Antwort.json, richtig?
Ich habe paar Funktionen, die bekommen die Daten von einem server über Holen, dann legen Sie Sie zu der sqlite-Datenbank. damit Sie nicht wieder alles.
im Beispiel oben, Holen etwas zurückgibt. aber meine Funktionen nicht. ja, kann ich diese Struktur nutzen, um javascript laufen meine Funktionen folglich? was ist die beste Praxis - /rechts-Lösung zu erreichen?
JS:
let query = [];
export default class Main extends Component(){
constructor(props){
super(props);
}
componentWillMount(){
this.getBookable();
this.getBooked();
this.runQuery();
this.redirectUser();
////i need this functions to run consequently. not all in same time, one after eachother
}
getBookable(){
let fetchedData = fetch(); ///Fetchs data from remote server
query.push('INSERT INTO bookable (data) VALUES (' + fetchedData + ')');
}
getBooked(){
let fetchedData = fetch(); ///Fetchs data from remote server
query.push('INSERT INTO booked (data) VALUES (' + fetchedData + ')');
}
runQuery(){
for(let i=0; i < query.length; i++){
db.transaction((tx) => {
tx.executeSql(query[i],[], (tx, results) => {
console.log('Query', query[f], 'Executed. results:', results);
}, (err)=>{
console.log('Something went wrong while executing query',query[i],'error is', err);
});
});
}
}
redirectUser(){
Actions.tabbar({type: 'reset'});
////Using redux. redirect user to another page
}
}
Erste, ich bekomme Buchbare Kurse, dann werden Kurse gebucht, schieben Sie Sie auf die Datenbank, die dann umleiten Benutzer zu einer anderen Seite über redux
Wie soll ich ein update für meinen code?
UPDATE :
aktualisierten code nach @Bergi :
ist das der richtige Weg?
JS:
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(){
let userlist = [];
let query = ["SELECT * FROM users"];
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);
for(let ind = 0; ind < len; ind++ ){
userlist[ind] = {
userId: results.rows.item(ind).userId,
userName: results.rows.item(ind).userName,
userMail: results.rows.item(ind).userMail,
active: results.rows.item(ind).active,
firstName: results.rows.item(ind).firstName,
lastName: results.rows.item(ind).lastName,
accessToken: results.rows.item(ind).access_token,
host: results.rows.item(ind).host,
};
}
} catch(err) {
console.log('Something went wrong while executing query', q, 'error is', err);
}
}));
});
return userlist;
}
async getBookable(users){
let results = [];
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 function GrabData(){
try {
let users = await getUsers();
//let [courses, register, evaluation] = await Promise.all([getCourses(users), getRegister(users), getEvaluation(users)]);
let [courses] = await Promise.all([getCourses(users)]);
//let query = [courses, register, evaluation];
let query = [courses];
await 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 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);
Ich bin mit react native-sqlite-Speicher :
https://github.com/andpor/react-native-sqlite-storage
- Was ist das
fetch
in deinem Beispiel? - Sie sollten nicht mit einem stateful
query
array. Lassen Sie stattdessen die Methoden zurück, die Ihre jeweiligen Abfragen ausgeführt werden. - holt json-Daten von einem remote-server. ich nicht schreiben die ganze Funktion gibt, als ich dachte, es ist nicht notwendig.
- Sollte nicht die Schleife innerhalb der Transaktion, um sicherzustellen, dass die Abfragen werden immer nacheinander ausgewertet?
- So
fetch
asynchron ist? Was genau tut er dafür? - lassen Sie mich update der Frage
- Es gibt eine Menge Dinge, die sich in Ihrem code. Ich empfehle split diese Frage in mehrere, weil die Antwort auf diese Frage, es geht um sehr breit, von der
async
JS-Schlüsselwort, um, wie Reagieren Einheimische arbeiten, oder die Redux-Architektur. - derzeit mein code ausgeführt wird, problem ist, der Benutzer wird auf eine andere Seite weitergeleitet, bevor die Ausführung von Abfragen, fertig. ich denke mein problem ist nicht über redux. meine Funktionen laufen in der gleichen Zeit, vor den vorherigen zu beenden. ich bin auf der Suche nach einer Lösung für das
- ich habe aktualisiert die Frage mit fetch
- Danke. Tun
db.transaction
undtx.executeSql
Unterstützung Rückrufe oder Versprechen? Welche Rahmenbedingungen sind Sie mit, verknüpfen Sie Ihr Google docs? - vielen Dank für deine Antwort, ich habe soeben details zum letzten Teil der Frage. ich bin mit react native-sqlite-Speicher
- Ah, das scheint bereits Unterstützung verspricht. Ich aktualisiert meine Antwort mit dem Teil, aber ich bin mir nicht sicher, ob das wie vorgesehen funktioniert, - die docs sind ein bisschen spärlich.
- vielen Dank 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht. Das bedeutet nur, dass es zurückkehren wird, ein Versprechen, wenn Sie aufgerufen, und Sie können die
await
Betreiber in der Funktion Körper.Ja, denn es nutzt
await
zu stoppen, Bewertung der Methode, bis das Versprechen aufgelöst wird.Sollten Sie Rendite verspricht - auch wenn Sie verspricht nichts, Sie konnte immer noch abgewartet werden.
Aber in Ihrem Fall, Sie tatsächlich sollte etwas zurückgeben. Ihre Globale statische
query
array ist eine schreckliche antipattern. Anstelle der Füllung mit Abfragen, jede Methode zurückgegeben werden soll (ein Versprechen für) eine Abfrage, die dann übergeben werden kann, um die executor auf einer pro-Instanz und pro-call-basis. Nur dann mit einem Transaktion wirklich beginnt Sinn zu machen.Ihr code sollte wie folgt Aussehen:
getUsers
sollten Sie nicht verwendenPromise.all(query.map(
wenn es nur eine einzige Abfrage; ähnlich inGrabData
es keinen Sinn macht zu nutzenPromise.all
auf einer single-element array. UndGrabData
sollte das wohl nicht nennenrunQuery
zweimal - warum nicht eine einzelne Transaktion? Aber wenn Sie sind auf der Suche nach mehr aussieht, sollten Sie der post eine neue Frage auf Code Überprüfen (vorausgesetzt, der code funktioniert) oder hier (sonst). Bitte nicht ständig ändern Sie Ihre Frage.