- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想将许多 future 批处理到一个请求中,该请求在达到最大批处理大小或达到自收到最早的 future 以来的最长时间时触发。
动机
在 flutter 中,我有许多 UI 元素需要显示 future 的结果,这取决于 UI 元素中的数据。
例如,我有一个地方的小部件和一个显示步行到某个地方需要多长时间的子小部件。为了计算步行需要多长时间,我向 Google Maps API 发出请求以获取到该地点的旅行时间。
将所有这些 API 请求批处理成一个批处理 API 请求会更加高效和经济。因此,如果小部件即时发出 100 个请求,则可以通过单个提供程序代理 future ,该提供商将 future 分批成对 Google 的单个请求,并将来自 Google 的结果解包到所有单独的请求中。
提供者需要知道何时停止等待更多 future 以及何时实际发出请求,这应该由最大“批量”大小(即旅行时间请求的数量)或您愿意的最大时间量来控制等待批处理发生。
所需的 API 类似于:
// Client gives this to tell provider how to compute batch result.
abstract class BatchComputer<K,V> {
Future<List<V>> compute(List<K> batchedInputs);
}
// Batching library returns an object with this interface
// so that client can submit inputs to completed by the Batch provider.
abstract class BatchingFutureProvider<K,V> {
Future<V> submit(K inputValue);
}
// How do you implement this in dart???
BatchingFutureProvider<K,V> create<K,V>(
BatchComputer<K,V> computer,
int maxBatchSize,
Duration maxWaitDuration,
);
create
上面的功能?
最佳答案
这听起来非常合理,但也非常专业。
您需要一种表示查询的方法,将这些查询组合成一个 super 查询,然后将 super 结果拆分为单独的结果,这就是您的 BatchComputer
做。然后你需要一个队列,你可以在某些条件下刷新它。
有一点很清楚,您需要使用 Completer
s 用于结果,因为当您想要返回 future 时,您总是需要它,然后才能获得值(value)或 future 来完成它。
我会选择的方法是:
import "dart:async";
/// A batch of requests to be handled together.
///
/// Collects [Request]s until the pending requests are flushed.
/// Requests can be flushed by calling [flush] or by configuring
/// the batch to automatically flush when reaching certain
/// tresholds.
class BatchRequest<Request, Response> {
final int _maxRequests;
final Duration _maxDelay;
final Future<List<Response>> Function(List<Request>) _compute;
Timer _timeout;
List<Request> _pendingRequests;
List<Completer<Response>> _responseCompleters;
/// Creates a batcher of [Request]s.
///
/// Batches requests until calling [flush]. At that pont, the
/// [batchCompute] function gets the list of pending requests,
/// and it should respond with a list of [Response]s.
/// The response to the a request in the argument list
/// should be at the same index in the response list,
/// and as such, the response list must have the same number
/// of responses as there were requests.
///
/// If [maxRequestsPerBatch] is supplied, requests are automatically
/// flushed whenever there are that many requests pending.
///
/// If [maxDelay] is supplied, requests are automatically flushed
/// when the oldest request has been pending for that long.
/// As such, The [maxDelay] is not the maximal time before a request
/// is answered, just how long sending the request may be delayed.
BatchRequest(Future<List<Response>> Function(List<Request>) batchCompute,
{int maxRequestsPerBatch, Duration maxDelay})
: _compute = batchCompute,
_maxRequests = maxRequestsPerBatch,
_maxDelay = maxDelay;
/// Add a request to the batch.
///
/// The request is stored until the requests are flushed,
/// then the returned future is completed with the result (or error)
/// received from handling the requests.
Future<Response> addRequest(Request request) {
var completer = Completer<Response>();
(_pendingRequests ??= []).add(request);
(_responseCompleters ??= []).add(completer);
if (_pendingRequests.length == _maxRequests) {
_flush();
} else if (_timeout == null && _maxDelay != null) {
_timeout = Timer(_maxDelay, _flush);
}
return completer.future;
}
/// Flush any pending requests immediately.
void flush() {
_flush();
}
void _flush() {
if (_pendingRequests == null) {
assert(_timeout == null);
assert(_responseCompleters == null);
return;
}
if (_timeout != null) {
_timeout.cancel();
_timeout = null;
}
var requests = _pendingRequests;
var completers = _responseCompleters;
_pendingRequests = null;
_responseCompleters = null;
_compute(requests).then((List<Response> results) {
if (results.length != completers.length) {
throw StateError("Wrong number of results. "
"Expected ${completers.length}, got ${results.length}");
}
for (int i = 0; i < results.length; i++) {
completers[i].complete(results[i]);
}
}).catchError((error, stack) {
for (var completer in completers) {
completer.completeError(error, stack);
}
});
}
}
void main() async {
var b = BatchRequest<int, int>(_compute,
maxRequestsPerBatch: 5, maxDelay: Duration(seconds: 1));
var sw = Stopwatch()..start();
for (int i = 0; i < 8; i++) {
b.addRequest(i).then((r) {
print("${sw.elapsedMilliseconds.toString().padLeft(4)}: $i -> $r");
});
}
}
Future<List<int>> _compute(List<int> args) =>
Future.value([for (var x in args) x + 1]);
关于flutter - Dart 中的批处理 future ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58178129/
我有一个相当冗长的命令行程序,它需要用户输入参数,然后使用这些参数进行处理。我想做的是将程序拆分为交互式和非交互式。我试图这样做,并打算让非交互式程序“调用”交互式程序并使用结果(参数),基于这些参数
谁能解释为什么我们在构造函数的参数中使用大括号。 class Cars { String carName; bool isAuto; // create the constructor
我想知道是否有Dart函数,例如PHP的 strrev()。如果没有,您能否请向我展示任何源代码如何自行实现? 谢谢。 最佳答案 我还没有在API中找到一个新的Dart用户(截至今天下午)。但是,以任
我有一个组件,我想根据一个 bool 值绑定(bind)一个不同的 css 类。我的组件代码中有以下内容: bindCssClass(div, "open", this, "task.isOpen")
我一直在研究如何在dart中播放.wav文件,并且已经能够通过dart:html库中定义的AudioElement成功完成此操作。但是,我对使用dart:web_audio库感兴趣,并且遇到了所有这些
Dart 是否旨在实现许多与 Haxe 相同的功能,以便能够针对其他语言和运行时?它是语言和工具的既定目标还是已知目标? 最佳答案 不。Dart 专门针对 web 应用程序开发(更具体地说,客户端 w
我正在尝试让 dart 正常工作。作为编辑器,我想使用 emacs dart-mode。我有两个关于在没有 dart 编辑器的情况下使用 dart 的问题: 1) 我是否需要手动调用 dart2js,
我正在使用列表来创建墨水瓶按钮。我想将列表放在一个单独的 dart 文件中,并将该文件导入到我使用列表的文件中。我不知道如何导入列表。 https://pastebin.com/mf0kvsGu 我制
我正在编写一个 flutter 应用程序,它通过蓝牙 (FlutterBlue) 向设备发送命令。该设备控制一些 LED。通信总体上运行良好,但是:在用户界面上,我有一个控制光强度的 slider 。
我正在使用来自 Get started: command-line and server apps | Dart 的说明.运行 dart --version 时,我得到: Dart VM versio
var c 返回 3 但 10/7=1.4285,其余为 0.4285,operator % 有错误? void main() { var a = 10; var b = 7; var c
如文档中所述: The const keyword isn’t just for declaring constant variables. You can also use it to create
在 Dart 中,我如何最好地编写相当于(不可变/值/非对象) 的代码输出或引用参数 ? 例如在 C#-ish 中,我可能会编码: function void example() { int re
Dart 支持的多重继承机制有哪些? 最佳答案 不,Dart 不支持多重实现继承。 Dart 具有接口(interface),并且与大多数其他类似语言一样,它具有多个接口(interface)继承。
我正在寻找有关如何制作可以采用位置子参数的 web 组件的资源。就像是: {{value}} // this could be any uneditable element {{value}
使用polymer.dart 的Dart 应用程序的pubspec.yaml 文件如下所示(来自Polymer.dart Code Lab): name: polymer_and_dart descr
今天我决定开始学习 Dart 语言,我从 Tour 开始,那里有一个例子: // These work in a const string. const aConstNum = 0; const aC
我正在查找字符串类和其他一些资源,试图了解如何格式化字符串。首先,我试图将数字填充到字符串中,但不是精度。 例子: int a = 0, b = 5, c = 15, d = 46; String
我知道的大部分是Javascript。我相信“列表”是 Dart 最接近数组的东西,但它们在技术上是一样的吗?将它们视为数组是错误的吗?同样, map 会被视为对象吗?我意识到可能存在差异,但进行这种
现在,白色背景刺痛了我的眼睛,因为这是一个looong的黑夜。是否可以从 Dart 编辑器 (v 0.1) 更改主题(更改为更暗的主题)?选择背景颜色和语法高亮怎么样? 最佳答案 是的,这是可能的,我
我是一名优秀的程序员,十分优秀!