让我们说我正在进行ajax调用。并且后端一次只返回10个项目。我可以使用' skip'参数,以获得更多元素。服务器还返回元素总数。因此,如果我想获得所有现有元素,我的工作流程应该如下:
递归函数不会在这里工作,对吧?那么如何使用发电机来实现呢?
我希望只获得必要的数据,例如。如果我调用.next()5次,它会进行5次调用,并获得50行,即使数据库中有总计有数百万行。
答案 0 :(得分:0)
对于使用promises的异步调用,你可以用生成器做的最多就是它返回promise。下面以jQuery ajax为例,您当然可以替换自己的promisified ajax方法。
function genGetData* (url, start, limit) {
while (start < start+2000) { // conditional is just a safety net
yield $.get(url, {start: start, limit: limit});
start += limit;
}
}
var getData = genGetData('foo.php', 0, 10);
// get first 30 rows
$.when(getData.next().value,getData.next().value,getData.next().value)
.then(function () {
var args = Array.prototype.slice.call(arguments);
args.forEach(function (data) {
console.log(data); // will be in order by set of results
});
});
将这种情况应用到您的情况中,您需要创建一个变量来保存总记录并将其传递给您的生成器,以便在第一次请求之后,您可以更新它以便生成器知道何时停止
function genGetData* (url, options) {
while (options.start < options.total) {
yield $.get(url, {start: options.start, limit: options.limit});
options.start += options.limit;
}
}
var options = {
start: 0,
limit: 10,
total: 1 // this just needs to be greater than start, we'll update it in a moment
}
var getData = genGetData('foo.php', options);
getData.next().value.then(function (data) {
options.total = data.total;
var promiseArray = [];
for (let promise of getData) {
promiseArr.push(promise);
}
$.when.apply(null, promiseArray).done(function () {
console.log(args); // data in order in chunks of 10, excluding the first 10
});
});
因此,当第一次在生成器上调用.next()时,我们访问它的promise并等待它完成,以便我们可以得到总数。在我们更新总数之后,我们然后在生成器上执行for循环以获取其余数据。然而,这仍然无法解决您将并行发送太多请求的事实。