Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 颤振,功能需要等待数据可用_Asynchronous_Flutter_Wait_Synchronous - Fatal编程技术网

Asynchronous 颤振,功能需要等待数据可用

Asynchronous 颤振,功能需要等待数据可用,asynchronous,flutter,wait,synchronous,Asynchronous,Flutter,Wait,Synchronous,我是颤振编程的新手。我试图理解异步函数调用,但偏离了轨道 我想以安全的方式在设备上存储数据。因此,在写入数据时,数据将被加密,而在读取数据时,数据将被解密。应用程序不知道设备上的数据已加密。 我创建了一个利用SharedReferences库的存储类。 读取功能的第二个功能是,应用程序将等待数据可用 我写了这样的东西 static String getString(String key) { SharedPreferences prefs = await SharedPrefere

我是颤振编程的新手。我试图理解异步函数调用,但偏离了轨道

我想以安全的方式在设备上存储数据。因此,在写入数据时,数据将被加密,而在读取数据时,数据将被解密。应用程序不知道设备上的数据已加密。
我创建了一个利用SharedReferences库的存储类。
读取功能的第二个功能是,应用程序将等待数据可用

我写了这样的东西

  static String getString(String key)  {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    return _decrypt(prefs.getString(key));   
  }
现在,编译器抱怨不需要等待语句

当我将函数更改为返回
Future
的异步函数时,它会工作。然而,我的等待问题上升到调用
getString
函数的地方。
目标:函数将返回解密的字符串,主线程需要等待数据可用

从OP的答案中添加,该答案应为编辑: 对不起,没有说得够具体。我的页面正在加载自己的线程。在线程中,我希望从存储中获取值。线程无法继续,因为下一条语句依赖于存储区中的数据

例如,我需要商店的用户名和密码才能登录。用户名和密码分别存储


当然,我可以嵌套'then'语句,但我认为为了源代码的可读性,最好等到值从存储中读取。

您必须添加关键字async和Future,如下所示:

static Future<String> getString(String key)  async { // ------> here
   SharedPreferences prefs = await SharedPreferences.getInstance();

   return _decrypt(prefs.getString(key));   
}

永远不要阻止主线程,因为它会阻止应用程序操作。您的初始化可能需要很长时间,系统可能会在必要时终止您的应用程序

为了解决您的问题,最好不要阻塞主线程,可以创建加载屏幕,等待数据加载完成,然后显示最终的应用程序屏幕

代码原型可能如下所示:

class HomePage extends StatefulWidget {
  @override
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  String data;

  @override
  void initState() {
    super.initState();

    loadData().then((data) {
      setState(() {
        this.data = data; 
      });
    });
  }

  Future loadData() async {    
    data = 'xxx'; // load your data from SharedPreferences
    return data;    
  }

  @override
  Widget build(BuildContext context) {
    if (data == null) {
      loadData();
      return LoadingScreen();
    } else {
      return MainScreen();
    }
  }
}
类主页扩展StatefulWidget{
@凌驾
HomePageState createState()=>HomePageState();
}
类HomePageState扩展了状态{
字符串数据;
@凌驾
void initState(){
super.initState();
loadData()。然后((数据){
设置状态(){
这个数据=数据;
});
});
}
Future loadData()异步{
data='xxx';//从SharedReferences加载数据
返回数据;
}
@凌驾
小部件构建(构建上下文){
如果(数据==null){
loadData();
返回加载屏幕();
}否则{
返回主屏幕();
}
}
}

用这种方式调用,这是我的函数& 设定状态是小鬼

checkInCart()async{
    bool pre=await storage.containsKey(key: '${widget.eventIndex}');
    if(pre) {
      setState(() {
        isavail=true;
        favorite=true;
      });

    }

  }
叫它进来

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    checkInCart();

  }

这项工作必须提前欢迎

这个问题回答了什么?如何回答?请注意
checkInCart()async{
    bool pre=await storage.containsKey(key: '${widget.eventIndex}');
    if(pre) {
      setState(() {
        isavail=true;
        favorite=true;
      });

    }

  }
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    checkInCart();

  }