使用队列并发上传图片

背景

最近在写图片上传功能,使用antd提供的upload组件,并使用beforeUpload函数拦截,再批量读进浏览器之后手动上传。

第一次实现

传输使用的协议是http2,如果不做处理,并发传输的数量没有限制。第一次的实现使用Promise.all,并发传输,测试时,使用单张16.7M的图片,同时上传20张,会给后端带来不小的压力,多次测试中都会有部分图片上传失败,返回502或504。

使用Promise.all的实现方式带来的问题是:

  1. 没有并发的数量限制,会占用大量带宽,同时给后端带来压力;
  2. Promise.all的执行方式是全部成功才算成功,有一个失败即算失败,就会将这个失败的结果返回,不管其他的项是否完成,这带来的问题是每一个失败的err没有办法单独隔离处理,导致没有办法进行后续操作,比如单独重新上传,也就是说,使用Promise.all没有办法单独对每一项进行操作,限制了灵活度。

优化的上传策略

改进的实现使用下面这种传输策略:

创建比如3个transmitter,点击发送按钮时,三个transmitter并发发出一张图片,哪个transmitter完成自己的发送任务,就去任务队列中拿下一张图片发送,直至全部图片发送完成。

下面是传输策略的实现。

阅读全文〉

基于链表的队列实现

使用链表能达到最优设计目标:

  1. 可以处理任意类型的数据
  2. 所需的空间总是和集合的大小成正比
  3. 操作所需的时间总是和集合的大小无关

在下面的实现代码中能看到队列和栈的区别,栈由于是后进先出,所以只涉及头部,操控一个first变量即可。队列是先进先出,所以要操控first和last两个Node变量。

阅读全文〉

DJ双栈算术表达式求值算法

看到p79,讲栈的一个应用——算术表达式求值,突然想起来这是来我现在这家公司面试的时候,被问的一道题。当年年少无知写计算器的时候,算术表达式求值用的是正则表达式的匹配(不涉及括号),面试给出的的答案也是这种办法。看到书里用栈来解决,真是牛逼。

阅读全文〉

关于promise的理解

基于回调函数的异步编程

回调函数真正的问题在于它剥夺了我们使用return和throw这些关键字的能力。相反,我们的整个diamante流程都是基于副作用的:一个函数会附带调用其他函数。1

并且,它会将我们通常在大部分编程语言中能获得的堆栈破坏。1

Primise给予我们的是在我们使用异步时丢失的最重要的语言基石:returnthrow以及堆栈1

阅读全文〉

ES6之后添加的日常开发用的到的新特性

数组的新函数

  1. Array.prototype.includes()

    判断一个数组是否包含一个指定的值,包含返回true,否则返回false

  2. Array.prototype.flat()

    这个方法按照一个可指定的深度递归遍历数组,将所有元素与遍历到的子数组中的元素合并为一个新数组返回(另外可以利用这个函数进行数组空项去除)。

阅读全文〉