如何让这个函数等待 JSON 数据准备好

Posted

技术标签:

【中文标题】如何让这个函数等待 JSON 数据准备好【英文标题】:How can I make this function wait for a the JSON data to be ready 【发布时间】:2021-04-26 03:05:38 【问题描述】:

我正在尝试让 initialVideoId 等待 keyy 函数等待,但我不知道如何去吧。

我正在使用 Flutter,我的工作是从 TMDB 获取视频密钥,但不知道如何使 initialVideoId 等待 JSON 数据在访问之前准备好。


  getVideoUrl() async 
    http.Response response = await http.get(
        'https://api.themoviedb.org/3/movie/$widget.movieId/videos?api_key=$kApiKey');

    // print(json.decode(response.body));

    String data = response.body;
    // data.length;

    var keyy = jsonDecode(data)['results'][0]['key'];
    // results[0].key
    print(keyy);
  
  

  // String link = 'e9waCtSVoZ0';

  YoutubePlayerController _controller;
  bool isPlaerReady = false;

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

    print(widget.movieId);
    getVideoUrl();
    // _controller = YoutubePlayerController(initialVideoId: keyy);
    this._controller = YoutubePlayerController(
      initialVideoId: keyy,
      flags: YoutubePlayerFlags(
        mute: false,
        autoPlay: true,
        disableDragSeek: true,
        loop: false,
        isLive: false,
        // forceHideAnnotation: true,
        forceHD: false,
        enableCaption: true,
      ),
    )..addListener(_videoPlayerListner);
  

  void _videoPlayerListner() 
    print(_controller.value.playerState.toString());
  

void isPlayReady()


  @override
  void deactivate() 
    _controller.pause();
    super.deactivate();
  

  @override
  void dispose() 
    _controller.dispose();
    super.dispose();
  


@override
  Widget build(BuildContext context) 
    // return Text(getVideoUrl());
    // 
      return YoutubePlayer(
        controller: _controller,
        showVideoProgressIndicator: true,
        progressIndicatorColor: Colors.blueAccent,
        topActions: <Widget>[
          SizedBox(width: 8.0),
          Expanded(
            child: Text(
              _controller.metadata.title,
              style: TextStyle(
                color: Colors.white,
                fontSize: 18.0,
              ),
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
            ),
          ),
        ],
        onReady: () 
          isPlaerReady;
        ,
        onEnded: (data) ,
      );
  



我按要求将我的构建方法添加到问题中

【问题讨论】:

您可以在问题中添加您班级的build 方法吗? 您可以在 FutureBuilder 小部件中调用 getVideoUrl(),然后根据响应,做任何您需要的事情 @Stel 你能解释得更好吗?我对颤动很安静 @fartem 我已经做到了 FutureBuilder 是一个小部件,您可以调用一个返回 Future 的函数(将要解决的问题),然后您可以在屏幕上构建一些东西。你可以在这里阅读更多信息:api.flutter.dev/flutter/widgets/FutureBuilder-class.html 【参考方案1】:

您可以按照建议使用 FutureBuilder 来执行此操作。

例如,您可以执行一个函数来获取视频密钥,如下所示:

Future getVideoKey() async 
  var result = await http.get('https://getkeyfromTMDB');
  return result;    

然后,当您获得结果时,调用您的小部件的构建方法。这是一个基于您的代码的示例,它可能无法开箱即用:

@override
  Widget build(BuildContext context) 
    future: getVideoKey(), //this line is important. this tells your app to wait for the response before building the ui.
    return FutureBuilder(
            future: getVideoKey(),
            builder: (context, snapshot) 
              if (snapshot.hasData) 
                return YoutubePlayer(
                  controller: _controller,
                  showVideoProgressIndicator: true,
                  progressIndicatorColor: Colors.blueAccent,
                  topActions: <Widget>[
                    SizedBox(width: 8.0),
                    Expanded(
                      child: Text(
                        _controller.metadata.title,
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 18.0,
                        ),
                        overflow: TextOverflow.ellipsis,
                        maxLines: 1,
                      ),
                    ),
                  ],
                  onReady: () 
                    isPlaerReady;
                  ,
                  onEnded: (data) ,
                );
               else 
                return Center(child: CircularProgressIndicator());
              
            );
  

【讨论】:

你没有说 initialVideoId 将如何获取它的数据 您只需将您已有的所有用于 initialVideoId 的代码放入 getVideoKey() 函数中。不需要太多其他东西。这样做是您的应用程序将等待 getVideoKey() 获得响应,完成初始化(在您的情况下为控制器)然后构建 ui。

以上是关于如何让这个函数等待 JSON 数据准备好的主要内容,如果未能解决你的问题,请参考以下文章

使风暴喷口等待螺栓准备好

5种io模式

如何让 vue 组件等到数据准备好渲染?

linux 等待队列

Linux等待队列原理与实现

如何等待异步函数 Swift