简体   繁体   English

React Native:处理对sqllite db的异步调用

[英]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调用并获取heightstandard值,并将这两个值作为一个名为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.

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