Futures/Promises, and tracking down bugs
简而言之,Futures (dart) 或 Promises (js) 似乎为可怕的回调提供了一种模糊有用的解决方案。
对于大型软件,例如,当您正在与之交谈的服务器开始返回垃圾,触发深埋在第三方代码中的迄今为止看不见的异常时,就会出现问题。在这一点上,在一个令人难以置信的长链中的某个地方,以 catchError 终止,您将成为新的"空指针异常"之类的幸运接收者。它从哪里来的?谁知道?显然,我们不会使用这些技术神奇地获得调用堆栈,并且没有任何有用的跟踪信息 - 在这个巨大的链中,某些特定的函数可能会被调用 50 次,并且在某些任意调用时,会引发错误.
遇到这种情况时最好采用什么策略?
即将推出的名为"区域"的功能在这里应该会有所帮助。另外,请查看
此示例打印"catchError 内部":
1 2 3 4 5 6 7 8 9 10 11 12 | import 'dart:async'; void main() { runZonedExperimental(() { new Future.value(1) .then((v) => v) .then((v) => throw new ArgumentError('testing')) .then((v) => v) .catchError((e) => print('inside of catchError')); }, onError: print); } |
这个例子打印 'in onError':
1 2 3 4 5 6 7 8 9 10 11 | import 'dart:async'; void main() { runZonedExperimental(() { new Future.value(1) .then((v) => v) .then((v) => throw new ArgumentError('testing')) .then((v) => v); }, onError: (e) => print('in onError')); } |
这个例子打印"in onError: Illegal argument(s): testing":
1 2 3 4 5 6 7 8 9 10 11 | import 'dart:async'; void main() { runZonedExperimental(() { new Future.value(1) .then((v) => v) .then((v) => throw new ArgumentError('testing')) .then((v) => v); }, onError: (e) => print('in onError: $e')); } |
此示例打印出堆栈跟踪,其中包含原始异常发生的文件和行号:
1 | #0 main.. (file:///Users/sethladd/dart/zoneexperiment/bin/zoneexperiment.dart:7:20) |
代码:
1 2 3 4 5 6 7 8 9 10 11 | import 'dart:async'; void main() { runZonedExperimental(() { new Future.value(1) .then((v) => v) .then((v) => throw new ArgumentError('testing')) .then((v) => v); }, onError: (e) => print(getAttachedStackTrace(e))); } |
区域应该在 1.0 之前退出实验。
getAttachedStackTrace 的文档:http://api.dartlang.org/docs/releases/latest/dart_async.html#getAttachedStackTrace
runZoned 的文档:http://api.dartlang.org/docs/releases/latest/dart_async.html#runZonedExperimental