await关键字不在飞镖中等待

时间:2020-06-10 23:40:03

标签: dart

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

代码如下:

 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;
}
}

1 个答案:

答案 0 :(得分:0)

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;
  }
}