You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Async/Await问题:等待助记词生成后调用私钥生成函数

解决Flutter中Async/Await异步流程问题:按顺序生成助记词、私钥并展示结果

原代码问题分析

  1. Future对象直接插值错误:Text('Result: $_getKey')会直接输出Instance of 'Future<String>',而非实际私钥结果。
  2. 状态判断逻辑错误:用mnemonic != ""判断结果是否就绪,忽略了私钥生成的异步状态,导致还未拿到私钥就提前展示错误内容。
  3. 异步流程健壮性不足:虽然当前generateMnemonic是同步方法,但如果后续改为异步,现有初始化方式会出现顺序执行问题。

修改后的代码实现

页面状态类代码

class _MyHomePageState extends State<MyHomePage> {
  String? mnemonic;
  late Future<String> _privateKeyFuture;

  @override
  void initState() {
    super.initState();
    // 串联助记词生成与私钥生成的异步流程
    _privateKeyFuture = _generatePrivateKey();
  }

  Future<String> _generatePrivateKey() async {
    final genAddress = GenAddress();
    // 先生成助记词
    final generatedMnemonic = genAddress.generateMnemonic();
    // 更新状态保存助记词(按需使用)
    setState(() {
      mnemonic = generatedMnemonic;
    });
    // 等待私钥生成完成后返回结果
    return genAddress.getPrivateKey(generatedMnemonic);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: DefaultTextStyle(
        style: Theme.of(context).textTheme.displayMedium!,
        child: FutureBuilder<String>(
          future: _privateKeyFuture,
          builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            List<Widget> children;
            if (snapshot.hasData) {
              // 成功获取私钥,展示结果
              children = <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text('助记词: $mnemonic'),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text('私钥结果: ${snapshot.data}'),
                ),
              ];
            } else if (snapshot.hasError) {
              // 处理错误场景
              children = <Widget>[
                Padding(
                  padding: const EdgeInsets.only(top: 16),
                  child: Text('生成失败: ${snapshot.error}'),
                ),
              ];
            } else {
              // 加载中状态
              children = const <Widget>[
                Padding(
                  padding: EdgeInsets.only(top: 16),
                  child: Text('正在生成密钥...'),
                ),
              ];
            }
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: children,
              ),
            );
          },
        ),
      ),
    );
  }
}

GenAddress类代码(保持原实现)

class GenAddress implements GetAddressETH {
  String hdPath = "m/44'/60'/0'/0";

  @override
  String generateMnemonic() {
    return bip39.generateMnemonic();
  }

  @override
  Future<String> getPrivateKey(String mnemonic) async {
    final isValidMnemonic = bip39.validateMnemonic(mnemonic);
    if(!isValidMnemonic) {
      throw '无效助记词';
    }
    final seed = bip39.mnemonicToSeed(mnemonic);
    final root = bip32.BIP32.fromSeed(seed);

    const first = 0;
    final firstChild = root.derivePath("$hdPath/$first");
    final privateKey = HEX.encode(firstChild.privateKey as List<int>);

    return privateKey;
  }
}

关键改动说明

  • 串联异步流程:通过_generatePrivateKey方法确保先完成助记词生成,再调用异步的getPrivateKey,严格保证执行顺序。
  • 正确处理FutureBuilder状态:根据snapshot的hasData、hasError及未完成状态分别展示对应UI,符合异步逻辑。
  • 正确展示结果:使用snapshot.data获取异步返回的私钥值,而非直接输出Future对象。

内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:25:32