我正在进行一个异步调用,该调用查询服务上的数据库,但此服务有一个一次输出数量的限制,因此我需要通过它发送的结果检查它是否达到了限制,并重复查询,直到它没有达到为止。
同步实体模型:
var query_results = [];
var limit_hit = true; #While this is true means that the query hit the record limit
var start_from = 0; #Pagination parameter
while (limit_hit) {
Server.Query(params={start_from : start_from}, callback=function(result){
limit_hit = result.limit_hit;
start_from = result.results.length;
query_result.push(result.results);
}
}
字符串
显然,上面的方法不起作用,我在这里看到了一些关于这个问题的其他问题,但是他们没有提到当你需要每个迭代等待最后一个迭代完成,并且你事先不知道迭代的数量时该怎么做。
我怎样才能把上面的异步化呢?我愿意使用类似承诺/延迟的逻辑来回答,但最好是干净的。
我可能会想到一种使用等待/超时的可怕方法,但必须有一种干净、聪明和现代的方法来解决它。
- 另一种方法是进行“预查询”以事先了解特征的数量,这样您就可以知道循环的数量,我不确定这是否是正确的方法。*
在这里,我们有时会使用Dojo,但是我找到的示例并没有解释当您有未知数量的循环https://www.sitepen.com/blog/2015/06/10/dojo-faq-how-can-i-sequence-asynchronous-operations/时该怎么做
5条答案
按热度按时间txu3uszq1#
虽然已经有很多答案了,但我仍然相信
async
/await
是最干净的方法。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
你可能需要巴别塔
https://babeljs.io/
JS异步逻辑语法从
callback
到promise
再到async/await
,它们都做同样的事情,当callback
嵌套很多时,我们需要像链一样的东西,然后承诺来了,当promise
进入循环时,我们需要一些东西使链更普通更简单,然后async/await
来了。但不是所有的浏览器都支持新语法,因此,babel
会将新语法编译为旧语法,这样您就可以始终使用新语法进行编码。lp0sw83n2#
如果你想使用一个循环,那么我认为没有(干净)的方式来做它没有承诺。
一种不同的办法如下:
你可以称之为递归的,但是由于查询是异步的,你不应该有调用栈限制等问题。
在ES6环境中使用promises,您可以使用async/await,我不确定Dojo是否可以这样做。
x6492ojm3#
在编写速率限制器或队列之前,您不会理解回调;)诀窍是使用计数器:在异步请求之前递增计数器,并在获得响应时递减计数器,这样您就知道有多少请求处于“飞行”状态。
如果服务器阻塞了,您需要将项目放回队列中。
您需要考虑的事项有很多:如果进程被终止,队列会发生什么变化?在发送另一个请求之前要等待多长时间?确保回调没有被调用很多次!您应该重试多少次?在放弃之前要等待多长时间?确保没有遗漏!(回调永远不会被调用)
当所有的边缘情况都考虑进去的时候,你会得到一个相当长而且不那么优雅的解。但是你可以把它抽象成一个函数!(它返回一个Promise或者任何你喜欢的)。如果你有一个用户界面,你也想显示一个加载条和一些统计信息!
8cdiaqws4#
每次都必须等待服务器响应。这里是一个封装的方法
dddzy1tm5#
您可以使用生成器函数Generators来实现这一点对于POC:
一些基础知识-使用星号
*
定义一个生成器-它公开一个返回下一个值的next函数-生成器可以在内部使用yield语句暂停,也可以在外部通过调用next()
继续- While(true)将确保生成器在limit
到达之前不会完成显然,生成器函数保持着它自己的状态。生成器函数公开了两个属性
{ value, done }
,你可以这样调用它您可能需要使用Server.Query方法来处理生成器回调。希望这对您有所帮助!干杯!