链接 更多延迟示例
延迟在 Ajax 中后台使用,但这并不意味着它们不能在其他地方使用。本部分描述了延迟将有助于抽象异步行为并解耦我们代码的情况。
链接 缓存
链接 异步缓存
当涉及到异步任务时,缓存可能有点要求苛刻,因为你必须确保某个给定键的任务只执行一次。因此,代码必须以某种方式跟踪入站任务。
1
2
|
|
缓存机制必须确保即使脚本尚未缓存,也只请求一次 URL。这展示了一些逻辑来跟踪绑定到给定 URL 的回调,以便缓存系统正确处理已完成和入站请求。
1
2
3
4
5
6
7
8
9
10
|
|
每个 URL 缓存一个 Promise。如果给定 URL 还没有 Promise,则创建一个延迟并发出请求。当请求完成时,延迟被解决(使用 defer.resolve
);如果发生错误,则延迟被拒绝(使用 defer.reject
)。如果 Promise 已存在,则回调附加到现有延迟;否则,首先创建 Promise,然后附加回调。此解决方案的一大优点是它将透明地处理已完成和入站请求。另一个优点是基于延迟的缓存将优雅地处理故障。Promise 最终会被拒绝,可以通过提供错误回调来测试它
1
|
|
链接 通用异步缓存
还可以使代码完全通用,并构建一个缓存工厂,该工厂将抽象出当键不在缓存中时要执行的实际任务
1
2
3
4
5
6
7
8
9
10
11
|
|
现在请求逻辑已被抽象出来,$.cachedGetScript()
可以重写如下
1
2
3
|
|
这将起作用,因为每次调用 $.createCache()
都会创建一个新的缓存存储库并返回一个新的缓存检索函数。
链接 图像加载
可以使用缓存来确保不会多次加载同一图像。
1
2
3
4
5
6
7
8
9
10
11
12
|
|
同样,以下代码段
1
2
|
|
无论 my-image.png
是否已加载或是否实际正在加载,都将起作用。
链接 缓存数据 API 响应
在您页面生命周期内被视为不可变的 API 请求也是完美的候选对象。例如,以下
1
2
3
4
5
6
7
8
9
10
11
|
|
将允许您在 Twitter 上执行搜索并同时缓存它们
1
2
|
|
链接 计时
此基于延迟的缓存不仅限于网络请求;它还可用于计时目的。
例如,您可能需要在一段时间后在页面上执行操作,以便吸引用户注意他们可能不知道的特定功能或处理超时(例如,对于测验问题)。虽然 setTimeout()
适用于大多数用例,但它无法处理即使在理论上已过期的计时器被稍后请求的情况。我们可以使用以下缓存系统来处理这种情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
|
新的 $.afterDOMReady()
帮助程序方法在 DOM 准备就绪后提供适当的计时,同时确保使用最少的计时器。如果延迟已过期,任何回调都将立即调用。
链接 一次性事件
虽然 jQuery 提供了所有可能需要的事件绑定,但处理仅应处理一次的事件可能会变得有点麻烦。
例如,您可能希望有一个按钮,它将在第一次单击时打开一个面板,然后将其保持打开状态,或者在第一次单击该按钮时执行特殊的初始化操作。在处理这种情况时,人们通常会得到如下代码
1
2
3
4
5
6
7
8
9
|
|
然后,稍后,您可能希望采取措施,但仅当面板打开时
1
2
3
4
5
|
|
这是一个非常耦合的解决方案。如果您想添加其他操作,则必须编辑绑定代码或全部复制。如果您不这样做,您唯一的选择是测试 buttonClicked
,并且您可能会丢失该新操作,因为 buttonClicked
变量可能是 false
,并且您的新代码可能永远不会执行。
我们可以使用延迟对象做得更好(为了简化起见,以下代码仅适用于单个元素和单个事件类型,但可以轻松地将其概括为具有多个事件类型的成熟集合)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
|
代码的工作原理如下
- 检查元素是否已为给定事件附加延迟
- 如果没有,则创建它并使其在事件第一次触发时得到解决
- 然后将给定的回调附加到延迟并返回承诺
虽然代码肯定更冗长,但它以模块化和解耦的方式使处理手头问题变得更加简单。但让我们首先定义一个帮助器方法
1
2
3
|
|
然后可以重新调整逻辑,如下所示
1
2
3
4
|
|
如果某个操作应该仅在稍后打开面板时执行
1
2
3
4
5
|
|
如果面板尚未打开,则不会丢失任何内容,该操作将仅推迟到单击按钮为止。
link 组合帮助器
单独来看,以上所有示例似乎都有点局限性。但是,当您将它们混合在一起时,承诺的真正力量就发挥作用了。
link 在第一次单击时请求面板内容并打开所述面板
以下是按钮的代码,单击该按钮时,将打开一个面板。它通过网络请求其内容,然后淡入内容。使用前面定义的帮助器,可以将其定义为
1
2
3
4
5
6
7
8
9
|
|
link 在第一次单击时在面板中加载图像并打开所述面板
另一个可能的目标是在单击按钮并加载所有图像后才使面板淡入。
此 HTML 代码看起来像
1
2
3
4
5
6
|
|
我们使用 data-src
属性来跟踪真实图像位置。使用我们的承诺帮助器处理我们的用例的代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
|
这里的诀窍是跟踪所有 $.loadImage()
承诺。稍后,我们使用 $.when()
将它们与面板 .slideDown()
动画结合起来。因此,当首次单击按钮时,面板将向下滑动,图像将开始加载。一旦面板完成向下滑动并且所有图像都已加载,则面板将淡入,并且仅在此时才会淡入。
link 在特定延迟后在页面上加载图像
为了在整个页面上实现延迟图像显示,可以使用 HTML 中的以下格式。
1
2
3
4
|
|
它所说的非常直接
- 加载
image1.png
并立即显示第三张图片,第一张图片在 1 秒后显示 - 加载
image2.png
并显示第二张图片在 1 秒后显示,第四张图片在 2 秒后显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
|
为了延迟加载图像本身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
|
此处,在延迟满足后加载图像。当您希望限制页面加载时的网络请求数量或网络请求时,这可能非常有意义。