显示 angulardart 进展的最佳做法是什么?
What is the best practice to show a progress in angulardart?
我试图展示 angulardart 的进步,并认为 Future 对此有好处。但后来我意识到 Future 必须递归才能显示进度,因为 Future returns 立即执行,然后执行冗长的操作。
如果我创建一个在满足结束条件之前调用自身的 Future,它将与进度条一起工作。但我认为这不是一个很好的做法,因为每次递归时这些调用都会增加堆栈上的内存。只需考虑一个遍历 10 亿个数据集的循环,该循环可能 运行 几个小时,并且每个循环都在当前 Future 中调用一个新的 Future。
是否有更好的方法来创建一个循环,该循环需要一定的时间来处理每个元素(包括调用必须异步完成的网站并评估 return 值)?在循环期间,用户应该看到显示他 "x/1000000 done".
的进度
我认为必须用 Future 来完成,因为 UI 需要在启动循环后重新加载,但递归 Future 对我来说似乎不是个好主意。
您需要未来立即在网络上 return 返回给您,因为它是一个单线程平台。如果异步操作 return 直到它完成,那么你就会挂起浏览器,这对用户来说不会是一个很好的体验。
相反,您有几个选择:
Dart 有能力让 future 看起来像是与 await 关键字同步。所以你可以这样做:
void performAction() async {
showProgress = true;
await expensiveRpc();
showProgress = false;
}
这需要中间的进度,因为您实际上并没有在进度条进行时更新进度条。也就是说,如果您没有真正从 RPC 获取进度事件,这可能是更好的解决方案。
现在,如果您的 RPC 或操作在进行过程中给您某种反馈,您可以使用流做一些更好的事情。
void performAction() {
showProgress = true;
expensiveRpc().listen((progress) {
if (progress.done) {
showProgress = false;
} else {
percentComplete = progress.value;
});
}
实际上,与进度本身相比,它更多地取决于与您交互的 RPC 或服务如何更好地更新进度。
与此同时,我立即认识到一个 Future 方法 returns 而无需在方法体中执行任何操作。所以解决方案很简单:
只要用一个Future声明rpc,在方法中做任何你需要做的,在调用它的时候,使用then(...)做你需要在收集数据后做的事情。
int progress = 0;
int progressMax = 100;
bool progressCanceled = false;
Future rpc(var data)
async{
for(progress=0; progress<progressMax, progress++)
{
// do whatever you need to do with data
if(progressCanceled)
return;
}
}
rpc(data).then(
{
if(progressCanceled)
return;
// do whatever is needed after having received that data
});
rpc 已执行,调用进程可以继续,同时 rpc 执行 rpc 必须执行的操作。主程序可以处理按钮点击以将 progressCanceled 设置为 true,rpc 方法将询问状态并在设置时停止处理。
我试图展示 angulardart 的进步,并认为 Future 对此有好处。但后来我意识到 Future 必须递归才能显示进度,因为 Future returns 立即执行,然后执行冗长的操作。
如果我创建一个在满足结束条件之前调用自身的 Future,它将与进度条一起工作。但我认为这不是一个很好的做法,因为每次递归时这些调用都会增加堆栈上的内存。只需考虑一个遍历 10 亿个数据集的循环,该循环可能 运行 几个小时,并且每个循环都在当前 Future 中调用一个新的 Future。
是否有更好的方法来创建一个循环,该循环需要一定的时间来处理每个元素(包括调用必须异步完成的网站并评估 return 值)?在循环期间,用户应该看到显示他 "x/1000000 done".
的进度我认为必须用 Future 来完成,因为 UI 需要在启动循环后重新加载,但递归 Future 对我来说似乎不是个好主意。
您需要未来立即在网络上 return 返回给您,因为它是一个单线程平台。如果异步操作 return 直到它完成,那么你就会挂起浏览器,这对用户来说不会是一个很好的体验。
相反,您有几个选择:
Dart 有能力让 future 看起来像是与 await 关键字同步。所以你可以这样做:
void performAction() async {
showProgress = true;
await expensiveRpc();
showProgress = false;
}
这需要中间的进度,因为您实际上并没有在进度条进行时更新进度条。也就是说,如果您没有真正从 RPC 获取进度事件,这可能是更好的解决方案。
现在,如果您的 RPC 或操作在进行过程中给您某种反馈,您可以使用流做一些更好的事情。
void performAction() {
showProgress = true;
expensiveRpc().listen((progress) {
if (progress.done) {
showProgress = false;
} else {
percentComplete = progress.value;
});
}
实际上,与进度本身相比,它更多地取决于与您交互的 RPC 或服务如何更好地更新进度。
与此同时,我立即认识到一个 Future 方法 returns 而无需在方法体中执行任何操作。所以解决方案很简单:
只要用一个Future声明rpc,在方法中做任何你需要做的,在调用它的时候,使用then(...)做你需要在收集数据后做的事情。
int progress = 0;
int progressMax = 100;
bool progressCanceled = false;
Future rpc(var data)
async{
for(progress=0; progress<progressMax, progress++)
{
// do whatever you need to do with data
if(progressCanceled)
return;
}
}
rpc(data).then(
{
if(progressCanceled)
return;
// do whatever is needed after having received that data
});
rpc 已执行,调用进程可以继续,同时 rpc 执行 rpc 必须执行的操作。主程序可以处理按钮点击以将 progressCanceled 设置为 true,rpc 方法将询问状态并在设置时停止处理。