【问题标题】:DART function, nested / inner functions variableDART 函数,嵌套/内部函数变量
【发布时间】:2014-08-19 18:17:02
【问题描述】:

我将以下代码作为匿名函数(也是函数字面量或 lambda 抽象),用于DART mailer

email(){ 
   ...
   emailTransport.send(envelope)
   .then((success) => print('Email sent! $success'))
   .catchError((e) => print('Error occured: $e'));
}

这很好,但我需要用“return”替换“print”,如下所示:

email(){ 
   ...
   emailTransport.send(envelope)
   .then((success) => return 'Email sent! $success')
   .catchError((e) => return 'Error occured: $e');
}

但是失败了,返回没有被识别!

我尝试了下面的代码,但也失败了。

email(){ 
   ...
   var msg;
   ...
   emailTransport.send(envelope)
   .then((success) => msg = 'Email sent! $success')
   .catchError((e) => msg = 'Error occured: $e');

 return msg;
}

但“msg”仍然为 NULL!

任何想法。

【问题讨论】:

    标签: nested dart mailer nested-function


    【解决方案1】:

    这是因为您的函数中的 return 不是正在执行您的代码的 Futures 链的一部分。您的功能立即返回;并且 emailTransport.send 方法还没有运行。

    你的函数需要返回一个 Future;我认为没有任何方法可以“阻止”并等待结果(如果有,您可能不想这样做!)。

    你可能想做这样的事情:

    Future email() {
      ...
      return emailTransport.send(envelope)
       .then((success) => 'Email sent! $success')
       .catchError((e) => 'Error occured: $e');
    }
    

    然后,任何调用该函数的东西都需要链接到未来:

    email()
      .then(msg => print(msg));
    

    编辑:根据评论

    您调用的原始方法是异步的,因此返回一个Future(例如,将来会完成的东西)。要使用此值执行任何操作,您需要将更多代码“链接”到末尾(因此,它也将返回 Future,因为它在第一个完成之前无法运行)。

    您可以分配给链式函数中的变量,例如。

    email().then((m) => msg = m);
    

    但是,这只会在异步操作完成后执行,因此在这行代码之后不会立即可用(这是您原始代码示例中的错误)。如果你想用价值做一些事情,你真的需要把它链接到未来:

    email()
      .then(doSomeOtherThing)
    
    doSomeOtherThing(String msg) {
      // Do more processing here
    }
    

    如果你不熟悉 Futures,Dart 网站上有一篇文章可能值得一读:Use Future-Based APIs

    它与 NodeJS 的工作方式非常相似,任何事情都不应该“阻塞”,相反,在异步/长时间运行的工作之后需要完成的工作实际上是在一个被标记到末尾的回调中,并且运行时位于在一个大循环中处理队列中的下一步。这里有更多关于此的信息:The Event Loop and Dart

    【讨论】:

    • 谢谢,运行完美,但如果我想更进一步并将返回的输出分配给主函数中的变量,我尝试了以下类似返回的msg = email().then((msg ) => msg),输出 msg 显示为“Instance of '_Future'”
    • @HasanAYousef 我在我的答案中编辑了更多信息,希望对您有所帮助。简而言之,你不能只是阻塞等待结果,你需要将所有依赖代码链接到未来。
    • 哦,可能还值得一提的是,Dart 将来会获得一个 await 关键字,这将简化此代码,使其看起来是同步的(没有 .then() 的链接,它将自动重写为此)。这将与 C# 的 await 类似(其中 Dart 中的 Future 大致相当于 C# 中的 ask)。
    • 非常感谢,这非常有效,正是我想要的。在阅读了您推荐给我的 2 页后,我发现了另一种很酷的方法,在某些情况下可能有用,它是:email().then((msg) => mymsg= msg).then((_) { / * 这里做更多处理 */ });
    • @HasanAYousef 很高兴它有帮助! FWIW,如果您不需要父作用域中的变量,email().then((msg) => mymsg= msg).then((_) { /* Do more processing here */ }); 最好写为email().then((msg) => /* Do more processing here */ });。我将它提取到我的答案中的一个单独的函数中,以防它有很多代码:)
    猜你喜欢
    • 2019-06-14
    • 2018-10-23
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多