如何使回调的纯js循环?
How to make pure js cycle of callbacks?
我有一个API需要从中查询N页数据。因为我不想让 API 过载,所以我想按顺序进行而不阻塞主线程。
代码应该是这样的:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
for (let page = 0; page < totalPages; page++) {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
});
}
但是这种方法有几个问题:
- 因为它是异步的,它只会 运行 所有并行请求,结果会导致 API 过载。我需要它们仍然 运行 异步,但每个都应该 运行 只有当前一个完成时。
- 由于所有调用都是异步的,到周期结束时我们仍然没有请求的数据 - 它将在后台加载。在将
res
返回到其他需要它的代码之前,我们需要以某种方式等待所有回调完成。
- 没有办法让每个回调都将其结果传递给下一个回调,这是当某些回调收到来自服务器的“停止加载”/“没有更多数据”请求时停止加载的唯一方法
有没有办法在不使用一些辅助库或承诺的情况下解决这些问题?只是普通的老香草 javascript。
对不起,如果有些地方看起来不清楚,我在 js 方面不是很有经验
你可以在这里使用一个简单的递归,像这样:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
const loader = page => {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
if (page < totalPages)
loader(++page)
else
console.log('DONE!');
});
}
loader(0);
我有一个API需要从中查询N页数据。因为我不想让 API 过载,所以我想按顺序进行而不阻塞主线程。
代码应该是这样的:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
for (let page = 0; page < totalPages; page++) {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
});
}
但是这种方法有几个问题:
- 因为它是异步的,它只会 运行 所有并行请求,结果会导致 API 过载。我需要它们仍然 运行 异步,但每个都应该 运行 只有当前一个完成时。
- 由于所有调用都是异步的,到周期结束时我们仍然没有请求的数据 - 它将在后台加载。在将
res
返回到其他需要它的代码之前,我们需要以某种方式等待所有回调完成。 - 没有办法让每个回调都将其结果传递给下一个回调,这是当某些回调收到来自服务器的“停止加载”/“没有更多数据”请求时停止加载的唯一方法
有没有办法在不使用一些辅助库或承诺的情况下解决这些问题?只是普通的老香草 javascript。 对不起,如果有些地方看起来不清楚,我在 js 方面不是很有经验
你可以在这里使用一个简单的递归,像这样:
var res = []; // all data from api
var totalPages = 10;
var pageSize = 100;
const loader = page => {
// load using jQuery ajax request
$.get('api.php', { page: page, page_size: pageSize }, function(result) {
res.push(...result); // add data to resulting array
if (page < totalPages)
loader(++page)
else
console.log('DONE!');
});
}
loader(0);