-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
怎样按触发顺序执行异步任务 #27
Labels
Comments
嗯,不错的异步问题,要看具体业务的要求,有时候是需要每次点击都要执行异步操作。 有时候业务要求,必须等待上一次操作完成后,才能执行下一次操作。 |
异步问题是核心问题 |
图文并茂很棒 👍 |
利用队列和变量锁来使得每个异步任务依次执行,很赞的思路。其实根据需求,如果只是需要按点击顺序展示 ,那么从性能上考虑,并发请求,结果排序是性能更好的。但是如果各个异步操作之间存在依赖关系,下个异步操作依赖于上个异步操作。那么这个方法真的非常好。 |
Open
并发请求的话excue那里稍微改造一下就能用, while(this.queues.length){
// single request
const task = this.queues.shift()
const result = await task()
this.results.push(result)
this._callback && this._callback(value);
// concurrent request
const batchTasks = this.queues.splice(0, this.REQUEST_SIZE)
const results = await Promise.all(batchTasks.map(t => t()))
this.results.push(result)
}
` |
这是来自QQ邮箱的假期自动回复邮件。
您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
1. 异步任务
我从具体的项目中分离出了一个有趣的问题,可以描述如下:
页面上有一个按钮,每次点击它,都会发送一个ajax请求,
并且,用户可以在ajax返回之前点击它。
现在我们要实现一个功能,
以按钮的点击顺序展示ajax的响应结果。
2. 准备活动
为了以后编码的方便,先将ajax请求mock一下,
然后,假设按钮的
id
为sendAjax
,3. 冷静再冷静
一开始,我们可能会想到这样的办法。
可惜,这是有问题的。
因为
click
事件,可能会在后面async函数还未返回之前,再次触发。导致前一个请求还未返回,后面又发起了新请求。
其次,我们可能还会想到,记录每一个请求的时间戳,将结果排序,
这也是有问题的,因为我们不知道未来还有多少次点击(<- 下文的关键信息),
如果无法拿到所有的结果,那么排序就有困难了。
那怎么办呢?
如果请求还未返回之前,能进行控制就好了。
4. 让我们Lazy一点
于是我想到了把新请求lazy化,放到一个队列中,
如果当前有其他任务在执行,就暂不处理。
否则,如果当前是空闲的,那就把队列中的任务都取出来,依次执行。
以上代码,我用了一个队列和变量锁,对新请求进行了管控。
其中的关键点是
execute
的异步性,我们看到
add
函数在尾部调用了this.execute();
,会立即返回。这样就不会阻塞JavaScript线程,可以多次调用
add
函数了。下面我们来看下它的使用方法吧,
5. 更远一些
上文中有一句话,启发了我,
迫使我从不同的角度重新考虑了这个问题。
我们提到,由于“我们不知道未来还有多少次点击”,所以是无法进行排序的。
因此,我发现这是一个和“无穷流”相关的问题。
即,我们不应该把事件看成回调,而是应该看成流(stream)。
所以,我们可以寻找响应式的方式来解决它。
以下两篇文章可以帮你快速回顾一下响应式编程(Reactive Programming)。
——也称反应式编程 _(:зゝ∠)_
你所不知道的响应式编程
函数响应式流库探秘
好了,下面我们要开始进行响应式编程了。
首先,
click
事件可以形成一个“点击流”,这里的
cont
指的是Continuation,可以参考上面提到的第二篇文章。其次,我们需要将这个“点击流”,变换成最终的“ajax结果流”,
并且保证“ajax结果流”的顺序,与“点击流”的顺序相同。
因此,问题在概念上就被简化了,
事实上,所有的
stream
连同operator
一起,构成了一个Monad
。下面我们来编写
operator
吧,用来对流进行变换,我们只要记着,“什么时候调用
cont
就什么时候把东西放到结果流中”,即可。我们再来看下怎么使用它,是不是更加通俗易懂了呀。
The text was updated successfully, but these errors were encountered: