[英]React Native : Handling Async calls to sqllite db
I am having a bit of struggle trying to understand how async
functions work in React Native. 我正在努力了解async
函数在React Native中的工作方式。
In this example I am invoking a sqllite db call via a async call and get values of height
and standard
and return both these values as an object called result
. 在这个例子中,我通过异步调用调用sqllite db调用并获取height
和standard
值,并将这两个值作为一个名为result
的对象返回。
Values exist in sqllite db as can be seen in the console output shown below. sqllite db中存在值,如下面显示的控制台输出中所示。
The method invoked from componentDidMount
lifecycle method is an async method. 从componentDidMount
生命周期方法调用的方法是异步方法。
As can be seen I am using await
to wait for the actual execution ( aka getting data from sqllite ) to complete. 可以看出我正在使用await
实际执行( 也就是从sqllite获取数据 )来完成。
Line X always returns as undefined. 第X行始终返回未定义。
Line Y does not seem to execute at all as the state does not get changed from the initial values of 100 & "asasd" at all. 线Y似乎根本不执行,因为状态根本没有从100的初始值和“asasd”改变。
I have eyeballed the code and I am not sure what I am missing here. 我已经对代码进行了观察,我不确定我在这里缺少什么。
Can someone take a look at it and let me know ? 有人可以看看它,让我知道吗?
App.js App.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import {
dropLogsTable,
createLogsTable,
getProfileHeightStandardfromDB,
getProfileHeightStandardPremade,
saveLogsRecord
} from '../src/helper';
export default class App extends Component {
state = {
logarray: [],
profileobject: {profileheight: 100, profilestandard: "asasd"},
};
componentDidMount() {
dropLogsTable();
createLogsTable();
this.fetchProfileData();
}
async fetchProfileData() {
console.log('Before Profile Fetch');
const result = await getProfileHeightStandardfromDB();
console.log('After Profile Fetch');
console.log('Height : '+result.profileheight);
console.log('Standard: '+result.profilestandard);
return result; //Line X
this.setState({profileobject:result}); //Line Y
}
render() {
return (
<View>
<Text>This is a test</Text>
<Text>Profile Height : {this.state.profileobject.profileheight} </Text>
<Text>Profile Standard : {this.state.profileobject.profilestandard}</Text>
</View>
);
}
}
helper.js helper.js
import { SQLite } from 'expo';
const db = SQLite.openDatabase({ name: 'swlt.db' });
let profileheight, profilestandard;
export function getProfileHeightStandardfromDB()
{
db.transaction(
tx => {
tx.executeSql('select standard, metricweight, metricheight, imperialheight, imperialweight, bmi, metricgoalweight, imperialgoalweight from profile', [], (_, { rows }) =>
{
//console.log(rows);
console.log(rows);
//console.log(parseFloat(rows._array[0].metricheight));
profileheight = parseFloat(rows._array[0].metricheight);
profilestandard = rows._array[0].standard;
console.log('Profileheight ===>'+profileheight);
console.log('Profilestandard ===>'+profilestandard);
}
);
},
null,
null
);
const profileobject = {profileheight, profilestandard};
console.log(profileobject);
return profileobject;
}
Output from Device and Console 设备和控制台的输出
You seem to have the this.setState
after a return
statement; 你似乎在return
语句之后有this.setState
; no code after the return statement will execute. return语句执行后没有代码。 Just put the this.setState
call before the return block 只需在返回块之前调用this.setState
Also, the function getProfileHeightStandardfromDB()
needs to be an async
function or needs to return a Promise
. 此外,函数getProfileHeightStandardfromDB()
需要是async
函数或需要返回Promise
。 Currently the method does not return a Promise
so theres no point awaiting it. 目前该方法没有返回Promise
所以没有必要等待它。 So heres what you would need to do 这就是你需要做的事情
function getProfileHeightStandardfromDB() {
return new Promise((resolve, reject) => {
db.transaction(
tx => {
tx.executeSql('select standard, metricweight, metricheight, imperialheight, imperialweight, bmi, metricgoalweight, imperialgoalweight from profile', [], (_, { rows }) => {
//console.log(rows);
console.log(rows);
//console.log(parseFloat(rows._array[0].metricheight));
profileheight = parseFloat(rows._array[0].metricheight);
profilestandard = rows._array[0].standard;
console.log('Profileheight ===>'+profileheight);
console.log('Profilestandard ===>'+profilestandard);
// what you resolve here is what will be the result of
// await getProfileHeightStandardfromDB();
resolve({ profileheight, profilestandard });
});
}, null, null);
});
}
You need to return data from getProfileHeightStandardfromDB
, db.transaction
is also async
function, so code outside the db.transaction
, will execute first before your console logs. 您需要从getProfileHeightStandardfromDB
返回数据, db.transaction
也是async
函数,因此db.transaction
之外的代码将在您的控制台记录之前首先执行。
You need to change getProfileHeightStandardfromDB
function like this : 您需要更改getProfileHeightStandardfromDB
函数,如下所示:
export function getProfileHeightStandardfromDB() {
return db.transaction(
tx => {
tx.executeSql('select standard, metricweight, metricheight, imperialheight, imperialweight, bmi, metricgoalweight, imperialgoalweight from profile', [], (_, {
rows
}) => {
//console.log(rows);
console.log(rows);
//console.log(parseFloat(rows._array[0].metricheight));
profileheight = parseFloat(rows._array[0].metricheight);
profilestandard = rows._array[0].standard;
console.log('Profileheight ===>' + profileheight);
console.log('Profilestandard ===>' + profilestandard);
const profileobject = {
profileheight,
profilestandard
};
console.log(profileobject);
return profileobject;
});
},
null,
null
);
}
Also change the order of last two lines of fetchProfileData
: 同时更改fetchProfileData
的最后两行的fetchProfileData
:
async fetchProfileData() {
console.log('Before Profile Fetch');
const result = await getProfileHeightStandardfromDB();
console.log('After Profile Fetch');
console.log('Height : '+result.profileheight);
console.log('Standard: '+result.profilestandard);
this.setState({profileobject:result}); //Line Y
return result; //Line X
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.