jQuery Deferred和Promise创建响应式应用程序详细介绍(5)


var openPanel = $( "#myButton" ).firstClick();
openPanel.done( initializeData );
openPanel.done( showPanel );


如果我们需要执行一些动作,只有当面板打开以后,所有我们需要的是这样的:

复制代码 代码如下:


openPanel.done(function() { /* perform specific action */ });


如果面板没有打开,行动将得到延迟到单击该按钮时。

组合助手
  单独看以上每个例子,promise的作用是有限的 。 然而,promise真正的力量是把它们混合在一起。

在第一次点击时加载面板内容并打开面板

  假如,我们有一个按钮,可以打开一个面板,请求其内容然后淡入内容。使用我们前面定义的助手方法,我们可以这样做:

复制代码 代码如下:


var panel = $( "#myPanel" );
panel.firstClick(function() {
$.when(
$.get( "panel.html" ),
panel.slideDownPromise()
).done(function( ajaxResponse ) {
panel.html( ajaxResponse[ 0 ] ).fadeIn();
});
});


在第一次点击时载入图像并打开面板

  假如,我们已经的面板有内容,但我们只希望当第一次单击按钮时加载图像并且当所有图像加载成功后淡入图像。HTML代码如下:

复制代码 代码如下:


<div>
<img data-src="image1.png" />
<img data-src="image2.png" />
<img data-src="image3.png" />
<img data-src="image4.png" />
</div>


我们使用data-src属性描述图片的真实路径。 那么使用promise助手来解决该用例的代码如下:

复制代码 代码如下:


$( "#myButton" ).firstClick(function() {
var panel = $( "#myPanel" ),
promises = [];
$( "img", panel ).each(function() {
var image = $( this ), src = element.attr( "data-src" );
if ( src ) {
promises.push(
$.loadImage( src ).then( function() {
image.attr( "src", src );
}, function() {
image.attr( "src", "error.png" );
} )
);
}
});

promises.push( panel.slideDownPromise() );

$.when.apply( null, promises ).done(function() { panel.fadeIn(); });
});


这里的窍门是跟踪所有的LoadImage 的promise,接下来加入面板slideDown动画。 因此首次点击按钮时,面板将slideDown并且图像将开始加载。 一旦完成向下滑动面板和已加载的所有图像,面板才会淡入。

在特定延时后加载页面上的图像
  假如,我们要在整个页面实现递延图像显示。 要做到这一点,我们需要的HTML的格式如下:

复制代码 代码如下:


<img data-src="image1.png" data-after="1000" src="https://www.jb51.net/placeholder.png" />
<img data-src="image2.png" data-after="1000" src="https://www.jb51.net/placeholder.png" />
<img data-src="image1.png" src="https://www.jb51.net/placeholder.png" />
<img data-src="image2.png" data-after="2000" src="https://www.jb51.net/placeholder.png" />


意思非常简单:

•image1.png,第三个图像立即显示,一秒后第一个图像显示
•image2.png 一秒钟后显示第二个图像,两秒钟后显示第四个图像
  我们将如何实现呢?

复制代码 代码如下:


$( "img" ).each(function() {
var element = $( this ),
src = element.attr( "data-src" ),
after = element.attr( "data-after" );
if ( src ) {
$.when(
$.loadImage( src ),
$.afterDOMReady( after )
).then(function() {
element.attr( "src", src );
}, function() {
element.attr( "src", "error.png" );
} ).done(function() {
element.fadeIn();
});
}
});


如果我们想延迟加载的图像本身,代码会有所不同:

复制代码 代码如下:


$( "img" ).each(function() {
var element = $( this ),
src = element.attr( "data-src" ),
after = element.attr( "data-after" );
if ( src ) {
$.afterDOMReady( after, function() {
$.loadImage( src ).then(function() {
element.attr( "src", src );
}, function() {
element.attr( "src", "error.png" );
} ).done(function() {
element.fadeIn();
});
} );
}
});


这里,我们首先在尝试加载图片之前等待延迟条件满足。当你想在页面加载时限制网络请求的数量会非常有意义。

结论
  正如你看到的,即使在没有Ajax请求的情况下,promise也非常有用的。通过使用jQuery 1.5中的deferred实现 ,会非常容易的从你的代码中分离出异步任务。 这样的话,你可以很容易的从你的应用程序中分离逻辑。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wddwds.html