代码之家  ›  专栏  ›  技术社区  ›  jared-nelsen

颤振中的DART期货问题:失败断言:第146行:“<optimized out>”:不正确

  •  3
  • jared-nelsen  · 技术社区  · 6 年前

    我正在为我的应用程序构建一个用户身份验证模块,我遇到了一些异步代码的问题。

    首先,这里是抛出的错误:

    e/flutter(17162):[错误:flutter/shell/common/shell.cc(188)]dart错误:未处理的异常: e/flutter(17162):“dart:async/future_impl.dart”:失败的断言:行146:“optimized out”:不是真的。 e/flutter(17162):0_断言错误。_dothrownew(dart:core/runtime/liberrors_patch.dart:40:39) e/flutter(17162):1断言错误thrownew(dart:core/runtime/liberrors_patch.dart:36:5) e/flutter(17162):2_futurelistener.handleerrror(dart:async/future_impl.dart:146:14) e/flutter(17162):3 future.propagattolisteners.handleerrror(dart:async/future_impl.dart:654:47) e/flutter(17162):4未来。诳传播学家(dart:async/future诳impl.dart:675:24) e/flutter(17162):5未来。完成错误(dart:async/future_impl.dart:494:5) e/flutter(17162):6同步完成器完成错误(dart:async/future impl.dart:55:12) e/flutter(17162):7完成错误(dart:async/future impl.dart:27:5) e/flutter(17162):8 asyncWaitCompleter.completeError(dart:async/runtime/libasync_patch.dart:40:18) e/flutter(17162):9 firebase auth.signinwithemail和password(package:firebase_auth/firebase_auth.dart) E/颤振(17162): e/flutter(17162):10 session.login.(套餐:情绪图/实用程序/会议。DART:31:24) e/flutter(17162):11诳rootzone.rununary(dart:async/zone.dart:1379:54) e/flutter(17162):12_futurelistener.handlevalue(dart:async/future_impl.dart:129:18) e/flutter(17162):13未来。35221;传播到isteners.handlevaluecallback(dart:async/future_impl.dart:642:45) e/flutter(17162):14未来。35827;传播到isteners(dart:async/future诳impl.dart:671:32) e/flutter(17162):15 future._完成(dart:async/future_impl.dart:476:7) e/flutter(17162):16完成(dart:async/future impl.dart:51:12) e/flutter(17162):17 asyncWaitCompleter.completer(dart:async/runtime/libasync_patch.dart:28:18) e/flutter(17162):18完成同步返回(dart:async/runtime/libasync_patch.dart:295:13) e/flutter(17162):19会话。35827; checkuseralreadyexists(包:mood诳map/utilities/session.dart) E/颤振(17162): e/flutter(17162):20 session.login(套装:mood_map/utilities/session.dart:27:11)

    以下是涉及到的功能:

    static final FirebaseAuth _authenticator = FirebaseAuth.instance;
    
    static void login(BuildContext context, String email, String password) async {
    
    email = email.trim();
    password = password.trim();
    
    //Check if the user already exists
    await _checkUserAlreadyExists(email).then((exists) {
    
      if(exists) {
    
        _authenticator.signInWithEmailAndPassword(email: email, password: password)
            .then((FirebaseUser user) { _loginSuccess(); })
            .catchError((Error e) { _loginFailure(context); });
    
      } else {
    
        Utilities.showMessageDialog(context, "That user doesn't exist. Please create an account below.");
    
      }
    
    });
    
    } 
    
    ----------------------------------------------------------------------
    
    static Future createUserAccount(BuildContext context, email, String password) async {
    
    //Check if the user already exists
    await _checkUserAlreadyExists(email).then((exists) {
    
      if(exists) {
    
        Utilities.showMessageDialog(context, "That user already exists. Please login or select another account.");
        AppNavigator.navigateToLoginScreen();
    
      } else {
    
        _authenticator.createUserWithEmailAndPassword(email: email, password: password)
            .then((FirebaseUser user) { _createUserSuccess(); })
            .catchError((Error e) { _createUserFailure(context); });
    
      }
    
    });
    
    }
    

    简而言之,对_authenticator.signonwithemailandpassword()的调用失败。我知道_authenticator实例正在处理其他函数,所以我知道它与firebase本身没有问题。

    我担心我做了错误的事情,从另一个异步函数内调用了另一个异步函数,authenticator.signonwithemailandpassword(),checkifuseralreadyexists()。从我所读的.then()块中似乎可以这样做,但错误消息似乎非常坚持,它与函数调用的异步性质的设置有关。

    思想?

    2 回复  |  直到 6 年前
        1
  •  3
  •   chemamolins    6 年前

    如果你使用 .then() 条款不使用 await .

    。然后() 等待 有两种不同的处理方法吗 Future 但不能用于相同的 未来 实例。

        2
  •  1
  •   Mitch Pankaj Negi    6 年前

    考虑使用 异步-等待 捕捉“最后一步”中的错误。这个答案 https://github.com/flutter/flutter/issues/22734 帮了我很多忙。

    下面是我从一个我不记得的源代码中得到的代码片段,它帮助我理解如何正确地使用 未来 我对它做了一些修改,以测试我的确切情况(补充 主4() DivideFullAsyncNested()。 功能)。希望有帮助。

    // SO 29378453
    import 'dart:async';
    
    import 'package:login_app/constants.dart';
    
    main() {
      // fails
      main1();
      main2();
      main3();
      main4();
    }
    
    Future<double> divide(int a, b) {
      // this part is still sync
      if (b == 0) {
        throw new Exception('Division by zero divide non-async');
      }
      // here starts the async part
      return new Future.value(a / b);
    }
    
    Future<double> divideFullAsync(int a, b) {
      return new Future(() {
        if (b == 0) {
          throw new Exception('Division by zero full async');
        }
        return new Future.value(a / b);
        // or just
        // return a / b;
      });
    }
    
    Future<double> divideFullAsyncNested() {
      return divideFullAsync(7, 8).then(
        (val) {
          return divideFullAsync(5, 0).then(
            (val2) {
              return Future(() {
                if (val2 == 1) {
                  throw Exception('Innermost: Result not accepted exception.');
                }
                return val2;
              });
            },
          ).catchError((err) => throw Exception('Inner:    $err'));
        },
      ).catchError((err) => throw Exception('Outter: $err'));
    }
    
    //Future<double> divideFullAsyncNested() {
    //  return divideFullAsync(9, 9).then(
    //    (val) {
    //      return Future(
    //        () {
    //          if (val == 1) {
    //            throw Exception('Result not accepted exception.');
    //          }
    //          return val;
    //        },
    //      );
    //    },
    //  ).catchError((err) => throw Exception(err.toString()));
    //}
    
    // async error handling doesn't catch sync exceptions
    
    void main1() async {
      try {
    //    divide(1, 0).then((result) => print('(1) 1 / 0 = $result')).catchError(
    //        (error) => print('(1)Error occured during division: $error'));
        var result = await divide(1, 0);
        print('(1) 1 / 0 = $result');
      } catch (ex) {
        print('(1.1)Error occured during division: ${ex.toString()}');
      }
    }
    
    // async error handling catches async exceptions
    void main2() {
      divideFullAsync(1, 0)
          .then((result) => print('(2) 1 / 0 = $result'))
          .catchError(
              (error) => print('(2) Error occured during division: $error'));
    }
    
    // async/await allows to use try/catch for async exceptions
    main3() async {
      try {
        await divideFullAsync(1, 0);
        print('3');
      } catch (error) {
        print('(3) Error occured during division: $error');
      }
    }
    
    main4() async {
    //  try {
    //    await divideFullAsyncNested();
    //  } on Exception catch (e) {
    //    print("(4) ${e.toString().replaceAll('Exception:', '').trimLeft().trimRight()}");
    //  }
      try {
        divideFullAsyncNested()
            .then((v) => print(v))
            .catchError((err) => print(Constants.refinedExceptionMessage(err)));
      } on Exception catch (e) {
        print("(4) ${Constants.refinedExceptionMessage(e)}");
      }
    }