连续同源异步操作队列

栏目: JavaScript · 发布时间: 5年前

内容简介:来自同源的多个异步操作可能引起异步冲突问题,特别是在网络请求时。同源操作产生了两个ajax请求,它们的请求结果将用于渲染同一个区域,然而由于网络问题,先发出的请求后返回,导致最终得到的界面是错误的。解决这个问题的最好办法,是利用原生XHR的abort方法,在后一次操作时,将前一次操作引起的ajax请求给cancel掉。但是在现实条件下,异步操作并非都有cancel操作。js原生的Promise没有,原生的fetch基于Promise也没有。基于Promise的很多工具都没有cancel操作。这种情况下怎么

问题的发现

来自同源的多个异步操作可能引起异步冲突问题,特别是在网络请求时。同源操作产生了两个ajax请求,它们的请求结果将用于渲染同一个区域,然而由于网络问题,先发出的请求后返回,导致最终得到的界面是错误的。

解决这个问题的最好办法,是利用原生XHR的abort方法,在后一次操作时,将前一次操作引起的ajax请求给cancel掉。

但是在现实条件下,异步操作并非都有cancel操作。js原生的Promise没有,原生的fetch基于Promise也没有。基于Promise的很多 工具 都没有cancel操作。这种情况下怎么解决这个问题呢?

其实方法是有的,就是直接丢弃Promise的推送,不执行它的resolve回调即可。这样,虽然异步操作已经执行了,但不会对现有的环境造成任何副作用。(虽然这样看上去浪费了异步操作这个资源。)

问题的思考

如何来判断是否要丢掉它的回调?我们可以创建一个队列,每次产生一个异步操作时,就将它加入到队列中,当队列中存在操作对象时,每次只取最后一个,等待它推送结果,执行它的回调,排在它前面的操作全部丢弃掉。

基于这样的想法,我写了一个工具。它为异步操作创建队列,并根据不同的场景实现不同的队列操作形式。你可以 通过这里阅读它的源码和文档 。它提供了4种可供选择的场景,开发者根据自己的实际场景选择使用其中的一种。

问题的解决

基于上述的思考,我最终发布了deferer-queue,你可以通过npm安装这个包,在自己的项目中使用它。它的操作模式超级简单,首先实例化一个queue对象,然后往这个queue push异步操作,异步操作被装在一个函数中被push进队列,它的回调函数一定是按照push的顺序执行。

import DefererQueue from 'deferer-queue'

const queue = new DefererQueue()

const defer1 = () => new Promise((resolve, reject) => { ... })
const defer2 = () => axios.get(...)
const defer3 = async () => ...

queue.push(defer1).then(() => { console.log(1) })
queue.push(defer2).then(() => { console.log(2) })
queue.push(defer3).then(() => { console.log(3) })复制代码

无论defer1-3中的谁,执行后谁先返回结果,控制台输出的结果永远是1 2 3(defer都成功的前提下),因为deferer-queue设计的就是保证回调是按push顺序执行。

要使用不同模式,只需要在实例化的时候,传入一个options对象,将mode设置为parallel/serial/switch/shift中的一个即可:

const queue = new DefererQueue({
  mode: 'switch',
})复制代码

其他的用法一样。这样,你的队列就会只采用最后一个push进队列的defer的结果,即使你的队列正在进行,只要有新的defer被push进去,那之前的所有操作都会被丢掉,队列运行结果只取最后一个操作的结果。

关于具体的API使用细则,你可以阅读它的 文档 。其中,利用axios的cancel能力那个地方非常有借鉴意义。

关于四种运行模式的详细解释,由于图片限制,请到我的博客进行阅读。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

微信力量

微信力量

谢晓萍等著 / 机械工业出版社华章公司 / 2015-10-28 / 59.00

微信俨然已进化为一种万能的连接器,拥有连接一切的能力,彰显出强大的连接力,无处不在,无所不能。本书将为你讲述连接为何能产生如此巨大的力量,这股力量正在商业和民生领域产生的变化,将为你展现微信生态进化的全景世界。 连接即入口,微信上的每一次有效的连接都会形成有效的入口。本书详细讲解了如何通过微信帮助餐饮、酒店、医院、零售、商场、电气、母婴、航空、客运、停车场、商圈、城市服务等数十个传统行业与它......一起来看看 《微信力量》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具