【问题标题】:await keyword doesn't wait in dartawait 关键字不在飞镖中等待
【发布时间】:2020-06-10 23:40:03
【问题描述】:

我正在使用 await 关键字等待方法完成并返回某些内容,然后使用 switch 语句根据方法返回值执行代码块,但它不会等待它的值,当我尝试打印输出为null的值!

代码如下:

 PhoneNumVerification status = await accountRecoveryAdmin.verifyUserPhoneNumber(phoneNum);
 print(status); // prints null because it didn't wait for the method to complete
 switch (status) {
 // some code
 }

方法如下:

enum PhoneNumVerification {
     failed,
     verified,
     wrongInput,
     smsVerificationNeeded
}

Future<PhoneNumVerification> verifyUserPhoneNumber(String phoneNum) async {
if (phoneNum.isEmpty ||
    !phoneNum.startsWith('01') ||
    phoneNum.length != 11) {
  return PhoneNumVerification.wrongInput;
}
try {
  await _auth.verifyPhoneNumber(
    phoneNumber: '+2$phoneNum',
    timeout: Duration(seconds: 30),
    verificationCompleted: (_) {
      return PhoneNumVerification.verified;
    },
    verificationFailed: (exception) {
      print(exception.message);
      return PhoneNumVerification.failed;
    },
    codeSent: (String verificationId, [int forceResendingToken]) {
      this.verificationId = verificationId;
      return PhoneNumVerification.smsVerificationNeeded;
    },
    codeAutoRetrievalTimeout: null,
  );
} catch (e) {
  print(e);
  return PhoneNumVerification.failed;
}
}

【问题讨论】:

  • 确实等了。问题是verifyUserPhoneNumber 没有在其成功路径上返回值。
  • 但它确实返回 PhoneNumVerification.verified!
  • verifyUserPhoneNumbertry 块不返回任何内容。它传递具有返回值的回调,但这些返回值永远不会返回给verifyUserPhoneNumber 的调用者。
  • 那我该如何纠正呢?
  • 您能否提供正确代码的答案?

标签: dart


【解决方案1】:

await accountRecoveryAdmin.verifyUserPhoneNumber(...) 确实在等待。问题是accountRecoveryAdmin.verifyUserPhoneNumber() 没有返回值。如果您在代码上运行dartanalyzer,它应该报告并非所有通过verifyUserPhoneNumber 的路径都返回一个值。

这是您的代码的简化版本,以使问题更加明显:

Future<PhoneNumVerification> verifyUserPhoneNumber(String phoneNum) async {
  // ...

  try {
    await _auth.verifyPhoneNumber(
      // ...
    );
  } catch (e) {
    print(e);
    return PhoneNumVerification.failed;
  }
}

您可以看到try 块没有返回值。它传递了具有return 语句的回调,但这只是指定了这些回调返回的内容;它们不是verifyUserPhoneNumber 返回的。

修复它的一种方法是让这些回调在verifyUserPhoneNumber 的范围内设置一个变量,然后返回:

Future<PhoneNumVerification> verifyUserPhoneNumber(String phoneNum) async {
  // ...

  try {
    PhoneNumVerification result;
    await _auth.verifyPhoneNumber(
      // ...
      verificationCompleted: (_) {
        result = PhoneNumVerification.verified;
      },
      verificationFailed: (exception) {
        // ...
        result = PhoneNumVerification.failed;
      },
      codeSent: (String verificationId, [int forceResendingToken]) {
        // ...
        result = PhoneNumVerification.smsVerificationNeeded;
      },
      // ...
    );

    return result;
  } catch (e) {
    print(e);
    return PhoneNumVerification.failed;
  }
}

编辑:

我不清楚FirebaseAuth.verifyPhoneNumber 返回的Future 代表什么。它可能只是表示请求已发送,而不是验证已完成。如果您希望您的功能等待验证完成,您可以这样做:

Future<PhoneNumVerification> verifyUserPhoneNumber(String phoneNum) async {
  // ...

  try {
    final verificationComplete = Completer<PhoneNumVerification>();
    await _auth.verifyPhoneNumber(
      // ...
      verificationCompleted: (_) {
        verificationComplete.complete(PhoneNumVerification.verified);
      },
      verificationFailed: (exception) {
        // ...
        verificationComplete(PhoneNumVerification.failed);
      },
      codeSent: (String verificationId, [int forceResendingToken]) {
        // ...
        verificationComplete(PhoneNumVerification.smsVerificationNeeded);
      },
      // ...
    );

    return await verificationComplete.future;
  } catch (e) {
    print(e);
    return PhoneNumVerification.failed;
  }
}

【讨论】:

  • 请确认您传递给_auth.verifyPhoneNumber 的回调之一实际上在_auth.verifyPhoneNumber 完成之前被调用。您可能还想将result 初始化为一些新的unknown 值,以便更清楚地了解是否正在调用任何回调。
  • 我现在测试了它,结果是它先打印未知,然后打印“代码发送”(我的意思是“代码发送”回调在验证功能完成后执行!)你知道为什么这发生了?!
  • 漏洞随后出现在_auth.verifyPhoneNumber 中,它显然在调用其中一个回调之前完成了返回的Future
猜你喜欢
  • 2021-04-05
  • 1970-01-01
  • 2021-09-15
  • 2019-05-07
  • 2021-03-11
  • 2019-05-09
  • 1970-01-01
  • 2019-10-28
  • 2020-05-16
相关资源
最近更新 更多