在前端开发中,我们常常需要同时进行多个异步请求。这时候,我们可以使用jQuery的$.Deferred()来处理异步请求,确保所有请求都完成后再执行下一步操作。但是,在循环中进行嵌套的Ajax调用时,会出现一些问题。本文将介绍如何使用$.Deferred()解决这些问题。
问题描述
假设我们需要向服务器发送100个请求,每个请求的URL不同,我们可以通过以下代码实现:
for (var i = 0; i < 100; i++) {
$.ajax({
url: '/api/' + i,
success: function (data) {
console.log('Request ' + i + ' completed.');
}
});
}然而,当我们运行上面的代码时,会发现控制台输出了100次“Request 100 completed.”。这是因为所有请求都是异步进行的,循环已经完成并且i的值变成了100,所以所有请求都使用了最后一个i的值。
为了避免这种情况,我们可以使用闭包来保留i的当前值:
-- -------------------- ---- -------
--- ---- - - -- - - ---- ---- -
--------- --- -
--------
---- ------- - --
-------- -------- ------ -
-------------------- - - - - - -------------
-
---
------
-现在,我们可以正确地输出每个请求的结果。但是,如果我们需要在所有请求完成后执行一些操作呢?
解决方案
为了解决这个问题,我们可以使用$.Deferred()来创建一个延迟对象,并将它们保存在数组中。
-- -------------------- ---- -------
--- --------- - ---
--- ---- - - -- - - ---- ---- -
--------- --- -
--- -------- - -------------
--------
---- ------- - --
-------- -------- ------ -
-------------------- - - - - - -------------
-------------------
-
---
-------------------------
------
-现在,我们已经在数组中保存了100个延迟对象。接下来,我们可以使用$.when()方法来等待所有异步请求完成并执行下一步操作:
$.when.apply(null, deferreds).done(function () {
console.log('All requests completed.');
});在这里,我们使用$.apply()方法来传递数组作为参数给$.when()方法。
示例代码
下面是完整的示例代码:
-- -------------------- ---- -------
--- --------- - ---
--- ---- - - -- - - ---- ---- -
--------- --- -
--- -------- - -------------
--------
---- ------- - --
-------- -------- ------ -
-------------------- - - - - - -------------
-------------------
-
---
-------------------------
------
-
------------------ ------------------------ -- -
---------------- -------- -------------
---总结
在循环中使用$.Deferred()和嵌套的Ajax调用时,需要注意变量作用域和异步请求的执行顺序。通过创建延迟对象并将它们保存在数组中,再使用$.when()方法等待所有异步请求完成,可以确保代码的正确性和可读性。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/29706