如何在Flutter中将future<String>分配给String变量

3

基本上,我有一个Future返回从安全存储中获取的jwt,我想将返回值分配给一个变量,比如说这个变量是token。它大致是这样的。

Future<String> getJwt() async {
      final secureStorage = SecureStorage();
      var jwt = await secureStorage.readSecureData('jwt');
      return jwt;
    }

我想要将其赋值给变量,像这样。

static String token = getJwt();

代码大致如下。

String? _token;

Future<String> getJwt() async {
      final secureStorage = SecureStorage();
      var jwt = await secureStorage.readSecureData('jwt');
      return jwt;
    }

void getJWT() async {
  String token = await getJwt(); 
  
}

class API {

  final token = getJWT();
  static Future<String> getData(String url) async {
    try {
      http.Response response = await http.get(Uri.parse(baseURL + url),
          headers: {
            "Content-type": "application/json",
            "Authorization": 'Bearer ' + token
          });

      return response.body;
    } catch (_) {
      return 'error';
    }
  }

  static Future<String> postData(String url, String json) async {
    try {
      http.Response response = await http.post(Uri.parse(baseURL + url),
          headers: {
            "Content-type": "application/json",
            'Authorization': 'Bearer ' + token
          },
          body: json);

      return response.body;
    } catch (_) {
      return 'error';
    }
  }
}

我已经尝试将字符串更改为Future,但它不起作用,如何解决这个问题?提前致谢。

3个回答

6

所以您需要一个异步函数来完成这个操作。我知道两种方法:

  1. 使用 async/await
  2. 使用 then

示例

// use async await
void main() async {
  String ret = await getAbc();
  print("ret: $ret");
  // ----- result -----
  // ret: abc
}

// use then
void main2() {
  getAbc().then((String ret) {
    print("ret: $ret");
  });
  // ----- result -----
  // ret: abc
}

Future<String> getAbc() async {
  await Future.delayed(Duration(seconds: 1));
  return "abc";
}



0

由于您正在使用Futures,我建议您将方法分开以填充变量。此外,请记住,Future函数需要像这样的异步符号:

您的函数

Future<String> getJwt() async {
  final secureStorage = SecureStorage();
  var jwt = await secureStorage.readSecureData('jwt');
  return jwt;
}

未来函数

late String _jwt;

setJwt(String jwt){
  _jwt = jwt;
}

Future<void> poblateJwt () async {
  await getJwt().then((value){
   setJwt(value);
  });
}

getJwtData() {
  return _jwt;
}

现在,您可以调用函数 getJwtData 并在任何地方使用它。最后一件剩下的事情是在您的应用程序中使用 FutureBuilder,并仅调用一次 "poblateJwt" 方法。像这样:
class YourWidget extends StatefulWidget {
  const YourWidget({Key? key};

  @override
  State<YourWidget> createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  late var _future;

  @override
  void initState() {
    _future = poblateJwt();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    //use this as a String value

    final jwt = getJwtData();

    return FutureBuilder(
      future: _future,
      ... rest of your  code
    );
  }


}

使用FutureBuilder,您不需要任何poblateJwt / getJwtData方法,也不需要late String _jwt;等 - 您所需的只是在initState中设置_future = getJwt();并直接在FutureBuilder内部使用它。 - pskink
我已经在另一个项目中尝试过这种方法,它非常有效,但是在这个项目中,我无法像那样分配它,因为它只是一个简单的类,我用它来服务于API。因此,我可能无法使用setState或InitState。我考虑使用全局变量,但对于一个简单的类,我无法使其工作。还有其他解决方案吗? - Adzf
@pskink 在 poblate 函数中的目标,并将其设置为 init 状态的 future 是为了为 late String 变量设置初始值。使用此方法将避免不必要的重建,因为如果您有一个调用“setState”函数的方法,这个小部件将会重新构建,这是大多数情况下都不想要的。这是一种好的实践,特别是如果您正在使用 Provider 模式或使用 Presenter 或 MVVM 架构。 - Rodrigo Molero
你不需要进行任何“不必要的重建” - 只需初始化 _future = getJwt();(不需要任何其他额外的 async 方法),并在 FutureBuilder 中使用 future: _future - 就这样。 - pskink
@pskink,你能否请用代码写出来。 - Adzf
代码在这里 - 看看 _calculation 变量是如何使用的。 - pskink

0

Future<String> getJwt() async {}

getJWT() 返回一个 Future,表示它将在未来返回某个值 (一个字符串)。这是异步编程的一部分。

因此,添加 await 基本上意味着我们需要等待响应,在未来的某个时刻会有响应。

static String token = await getJwt();

您可以观看 Flutter 团队的 精彩教程关于异步和等待


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接