考虑一系列步骤,这些步骤需要在准备繁重的网页时执行:
<Window x:Class="wpftest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:wpftest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Border Opacity="0.5" Grid.ZIndex="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<MediaElement Height="300" Width="300"
Source="c:\us\Resources\loader.gif"
LoadedBehavior="Play"
Stretch="Uniform" SpeedRatio="1" IsMuted="False" />
<TextBlock Grid.Row="1" Text="Loading..." HorizontalAlignment="Center"/>
</Grid>
</Border>
<!-- Controls -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox/>
<Label Grid.Row="1" Content="Some Label"></Label>
<TextBox Grid.Row="2"/>
</Grid>
</Grid>
每个步骤可能需要100毫秒到几秒的范围:但我们事先不确定每个步骤需要多长时间。
至少在step1();
step2();
..
stepk();
/ Promise
到达街道之前,我的理解是我们使用回调和await
。
但我们怎样才能避免这种情况迅速变得笨拙?按照以下顺序,我们有两个问题:
setTimeout
- 到嵌套函数调用前两步(K):
argK
那么如何构建这些顺序步骤,以便我们不会在整个函数链中发送function step1(args1,args2,args3,..) {
// do work for step1 using args1
setTimeout(function() {step2(args2,args3);}, [some timeout..]);
}
function step2(args2,args3,..) {
// do work for step2 using args2
setTimeout(function() {step3(args3 [, args4, args5 ..]);}, [some timeout..]);
}
不断增长的列表?
注意:对于某些情况,args
可能是一种有用的方法:但我希望能够从本地文件系统提供服务,这显然排除了它们:
http://blog.teamtreehouse.com/using-web-workers-to-speed-up-your-javascript-applications
受限制的本地访问
如果直接提供网页,Web Workers将无法工作 来自文件系统(使用file://)。相反,你需要使用一个 本地开发服务器,如XAMPP。
答案 0 :(得分:1)
没有承诺或异步等待,你必须做回调地狱风格
function step1(a,b,c){
setTimeout(() => {
step2():
}
}
或者您可以将引用传递给下一步
如果step2依赖于step1的结果
function step1(a,b,c, done){
setTimeout(() => {
done(a,b,step3):
}
}
function step2(d,e,done){
setTimeout(() => {
done(e):
}
}
step1("cat","dog","mouse", step2);
如果您想手动将args传递给step2,并从step1
获取结果function step1(a,b,c, done){
setTimeout(() => {
done(a):
}
}
function step2(d,e,done){
return function(step1a){
setTimeout(() => {
done(step1a, d):
}
}
}
step1("cat","dog","mouse", step2("d","e", step3);
如果没有Promisifying你的异步行动或实现你自己的承诺风格,这可能会很干净。
答案 1 :(得分:0)
我一直在阅读generator functions,看来它们可能是一个普通的JS解决方案。
Alex Perry wrote a great article及相关演示:
function step1() {
setTimeout(function(){
gen.next('data from 1')
}, 500);
}
function step2(data) {
setTimeout(function(){
gen.next(`data from 2 and ${data[0]}`)
}, 700);
}
function step3() {
setTimeout(function(){
gen.next('data from 3')
}, 100);
}
function *sayHello() {
var data = [];
data.push(yield step1());
data.push(yield step2(data));
data.push(yield step3(data));
console.log(data);
}
var gen = sayHello();
gen.next();
&#13;
在上面的示例中,每个异步请求都返回一个伪数据。每个连续步骤接收包含先前响应的数组,因此可以使用先前的响应。