React Native:同步运行函数

2024-01-06

我是面向对象编程的新手。我对承诺/异步/同步运行函数的了解只是基础。我非常感谢您的时间和关注!

这是 React-Native 文档中的示例:

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

正如我从上面的代码中了解到的, getMoviesFromApi 被声明为异步函数。这意味着它将依次执行函数。正确的?如果不对请纠正!

它会首先等待 fetch 完成然后调用response.json,对吧?

我有几个函数,通过 fetch 从服务器获取数据,然后将它们插入到 sqlite 数据库中。所以他们不返回任何东西。

在上面的例子中,fetch 返回一些东西。但我的功能不是。那么,我可以使用这个结构让 javascript 运行我的函数吗?实现这一目标的最佳实践/正确的解决方案是什么?

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
  }
  
}
First, i get bookable courses, then booked courses, insert them to database, then redirect user to another page via redux How should i update my code?

UPDATE :

根据@Bergi更新代码: 这是正确的方法吗?

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

我正在使用react-native-sqlite-storage:https://github.com/andpor/react-native-sqlite-storage https://github.com/andpor/react-native-sqlite-storage


getMoviesFromApi被声明为async function。这意味着它将依次执行函数。

不。这只意味着它在调用时会返回一个承诺,并且您可以使用await函数体中的运算符。

它会首先等待 fetch 完成然后调用response.json,对吧?

是的,因为它使用await停止对该方法的评估,直到承诺解决为止。

我有几个函数,通过 fetch 从服务器获取数据,然后将它们插入到 sqlite 数据库中。所以他们不返回任何东西。

他们应该回报承诺——即使他们的承诺毫无意义,他们仍然可以被等待。

但就你而言,他们实际上should返回一些东西。您的全球静态query数组是一个可怕的反模式。每个方法应该返回一个查询(承诺),而不是用查询填充它,然后可以在每个实例和每个调用的基础上将其传递给执行器。然后才使用交易实际上开始有意义了。

您的代码应如下所示:

class Main extends Component() {
  …
  async getBookable(){
    var response = await lfetch(host, {
      method: 'POST',
      headers: …
    });
    var responseData = await response.json();
    return 'INSERT INTO bookable (data) VALUES (' + responseData + ')'); // beware of SQL injections!!!
  }

  getBooked(){
    // the very same - here written without async/await:
    return fetch(host, {
//  ^^^^^^ important - return a promise
      method: 'POST',
      headers: …
    })
    .then(response => response.json())
    .then(responseData => {
      return 'INSERT INTO booked (data) VALUES (' + responseData + ')';
    });
    // don't `catch` anything, don't call `done` - just return the promise chain
    // errors will be handled in the try/catch below
  }

  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 getStore() {
    try {
      // actually you can fetch these in parallel, right?
      let [bookable, booked] = await Promise.all([getBookable(), getBooked()]);
      let query = [bookable, booked];
      await runQuery(query);
      redirectUser();
    } catch(error) {
      console.error(error);
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React Native:同步运行函数 的相关文章

随机推荐

  • UIView 动画后 UIView 内的 UIButton 不起作用

    我在这个论坛上看到了很多问题 这些问题给出了这个主题 UIButton inside a UIView when animated does not work 的答案 但是在尝试了类似的答案之后 a UIViewAnimationOptio
  • R 中的函数工厂

    我尝试通过返回专门函数的字典来提出一个函数工厂 或多或少类似于函数式编程风格 我尝试在下面的代码中执行此操作 require hash names c aa bb cc funs hash for i in seq length names
  • PHP 中 ::(双冒号)和 ->(箭头)有什么区别?

    PHP 中有两种不同的方法来访问方法 但是有什么区别呢 response gt setParameter foo bar and sfConfig set foo bar 我假设 gt 带有大于号或 V 形的破折号 用于变量函数 并且 双冒
  • 将 this 传递给函数的基本查询

    我正在尝试更好地理解 JavaScript function foo console log this normal function call foo this will refer to window 当我尝试将其传递给函数时 它会抛出
  • 如何判断这个内存泄漏是从哪里来的呢?

    如何确定代码中的内存泄漏来自何处 除了我的应用程序中的 main 函数之外 它没有引用任何内容 看来您正在尝试同时使用 NSZombieEnabled 和泄漏 这两种诊断技术不能一起工作 NSZombieEnabled 使所有已释放的对象都
  • 我应该如何在 Perl 中序列化代码引用?

    我希望nstore一个 Perl 哈希值 其中还包含代码引用 按照此perldoc http perldoc perl org Storable html CODE REFERENCEShttp perldoc perl org Stora
  • 为什么二叉搜索树中的查找时间复杂度为 O(log(n))?

    我可以看到 当在 a 中查找值时 如何BST每次将节点与我们要查找的值进行比较时 我们都会留下一半的树 但是我不明白为什么时间复杂度是O log n 所以 我的问题是 如果我们有一个包含 N 个元素的树 为什么查找树并检查特定值是否存在的时
  • 从 PHP 文本中提取 URL

    我有这样的文字 string this is my friend s website http example com I think it is coll 如何将链接提取到另一个变量中 我知道应该特别使用正则表达式preg match 但
  • .NET System.IO.BinaryWriter 写入的原始字节是否可以被其他平台读取?

    背景 我正在手动将大数据块写入二进制文件System IO BinaryWriter 我之所以选择这种方法 是因为与各种其他序列化和反序列化方法相比 它的性能得到了提高 我目前正在使用System IO BinaryReader Quest
  • 如何在 VS Code 中调试 vue js 应用程序?

    我使用创建了新的 vue js 应用程序vue init webpack my test3 在 VS Code v1 7 1 中 我尝试调试此应用程序和默认值launch json程序设置为 configurations type node
  • 如何处理nginx反向代理https到http方案重定向

    我已经将 nginx 设置为托管 jenkins 和其他一些应用程序的 ubuntu 实例上的反向代理 我使用 nginx 根据相对路径路由到各种应用程序 从客户端到 nginx 的所有流量都通过 https 进行 在防火墙后面 nginx
  • 在lisp中如何定义这样的常量?

    在Python中可以做到这一点 EMPTY PAWN KNIGHT BISHOP ROOK QUEEN KING BPAWN range 8 你会如何在 lisp 中做等价的事情 在 Lisp 中 只使用符号会更惯用 通常作为自评估关键字符
  • C# 中的方差规则

    The 方差有效性的精确规则 http blogs msdn com b ericlippert archive 2009 12 03 exact rules for variance validity aspx有点模糊而且不具体 我将列出
  • 扩展第一个容器以输出额外的 div 属性

    我开始将 pelican 与 reStructuredText 一起使用rst页面格式 我有自定义 javascript jQuery 的东西 我想用 div 属性来控制 比如data default tpl basename 具有嵌套内容
  • 上传文件并验证文件扩展名和文件大小 MVC 5

    我使用下面的代码来上传并检查文件扩展名和文件大小 Update 2控制器 public ActionResult Create Bind Include anak ID Pubdate kind title file details lin
  • 具有静态和响应宽度的两列模板

    有时我们需要结合百分比和固定值来计算尺寸 特别是在创建一些响应式布局时 就我而言 我只发现两种方法可以在纯 CSS 中实现所需的效果 Problem 让我们快速看一下这个问题 我们需要创建一个拉伸到页面整个宽度的两列布局 其中一列具有恒定的
  • Javascript:保留窗口对象引用?

    我的 javascript 代码打开一些窗口槽 var win window open 我将 win 引用与所有其他打开的窗口一起存储在一个数组中 一切正常 直到开启器刷新为止 所以我想要实现的是在加载 主 窗口时取回对打开的窗口的所有引用
  • 如何将 future 移至 lambda 表达式

    我正在使用 Visual Studio 2013 我想实现这行代码 f p get future auto task f std move f use f 我知道解决方案here https stackoverflow com questi
  • 使用枚举序数是个好习惯吗?

    我有一个枚举 public enum Persons CHILD PARENT GRANDPARENT 使用有什么问题吗ordinal 检查枚举成员之间的 层次结构 的方法 我的意思是 使用它时除了冗长之外是否有任何缺点 当有人将来可能会意
  • React Native:同步运行函数

    我是面向对象编程的新手 我对承诺 异步 同步运行函数的了解只是基础 我非常感谢您的时间和关注 这是 React Native 文档中的示例 async function getMoviesFromApi try let response a