From 70b86f556e16b985cff2666dd6ef9e7f7217937a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=A4=9A=E7=9B=8A?= Date: Thu, 14 Apr 2022 19:16:08 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E5=8E=BB=E9=99=A4=E6=9C=89=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E9=A3=8E=E9=99=A9=E7=9A=84=20async=20=E5=BA=93?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=20(#4051)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 去除有安全风险的 async 库依赖 * 去掉 console.log --- docs/zh-CN/components/form/input-file.md | 8 +++-- examples/loader.ts | 1 - mock/cfc/mock/upload/chunkApi.json | 7 ++++ mock/cfc/mock/upload/finishChunkApi.json | 7 ++++ mock/cfc/mock/upload/startChunkApi.json | 8 +++++ package.json | 1 - src/renderers/Form/InputFile.tsx | 42 +++++++++++++++--------- 7 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 mock/cfc/mock/upload/chunkApi.json create mode 100644 mock/cfc/mock/upload/finishChunkApi.json create mode 100644 mock/cfc/mock/upload/startChunkApi.json diff --git a/docs/zh-CN/components/form/input-file.md b/docs/zh-CN/components/form/input-file.md index adbd366e6..87add56a6 100755 --- a/docs/zh-CN/components/form/input-file.md +++ b/docs/zh-CN/components/form/input-file.md @@ -105,6 +105,8 @@ order: 21 - `chunkApi` 用来接收每个分块上传 - `finishChunkApi` 用来收尾分块上传 +还可以通过 `concurrency` 控制并行数量,默认是 3 + ### startChunkApi 用来做分块前的准备工作,一个文件只会调用一次。如果出错了,后续的分块上传就会中断。 @@ -293,7 +295,7 @@ order: 21 | maxSize | `number` | | 默认没有限制,当设置后,文件大小大于此值将不允许上传。单位为`B` | | maxLength | `number` | | 默认没有限制,当设置后,一次只允许上传指定数量文件。 | | multiple | `boolean` | `false` | 是否多选。 | -| drag | `boolean` | `false` | 是否为拖拽上传 | | +| drag | `boolean` | `false` | 是否为拖拽上传 | | joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) | | extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) | | delimiter | `string` | `,` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) | @@ -311,6 +313,7 @@ order: 21 | startChunkApi | [API](../../../docs/types/api) | | startChunkApi | | chunkApi | [API](../../../docs/types/api) | | chunkApi | | finishChunkApi | [API](../../../docs/types/api) | | finishChunkApi | +| concurrency | `number` | | 分块上传时并行个数 | ## 事件表 @@ -329,8 +332,9 @@ order: 21 | value | `string` | 上传成功后返回的 url | | state | `string` | 文件当前状态,值可为 `pending` `uploaded` `invalid` | | error | `string` | 错误信息 | + ## 动作表 | 动作名称 | 动作配置 | 说明 | | -------- | -------- | ---- | -| clear | - | 清空 | \ No newline at end of file +| clear | - | 清空 | diff --git a/examples/loader.ts b/examples/loader.ts index e18d137fc..ccc5db3ea 100644 --- a/examples/loader.ts +++ b/examples/loader.ts @@ -26,7 +26,6 @@ 'amis/embed': __moduleId('./embed.tsx'), 'amis@@version/embed': __moduleId('./embed.tsx'), 'prop-types': __moduleId('prop-types'), - 'async/mapLimit': __moduleId('async/mapLimit'), 'qs': __moduleId('qs'), 'path-to-regexp': __moduleId('path-to-regexp'), 'history': __moduleId('history') diff --git a/mock/cfc/mock/upload/chunkApi.json b/mock/cfc/mock/upload/chunkApi.json new file mode 100644 index 000000000..a89b12efe --- /dev/null +++ b/mock/cfc/mock/upload/chunkApi.json @@ -0,0 +1,7 @@ +{ + "status": 0, + "msg": "", + "data": { + "eTag": "016bd9b68ddd5cd7318875da3ea28207" + } +} diff --git a/mock/cfc/mock/upload/finishChunkApi.json b/mock/cfc/mock/upload/finishChunkApi.json new file mode 100644 index 000000000..f88fcc67b --- /dev/null +++ b/mock/cfc/mock/upload/finishChunkApi.json @@ -0,0 +1,7 @@ +{ + "status": 0, + "msg": "", + "data": { + "value": "https://xxxx.cdn.bcebos.com/images/JSSDK_page-xxxxx.zip" + } +} diff --git a/mock/cfc/mock/upload/startChunkApi.json b/mock/cfc/mock/upload/startChunkApi.json new file mode 100644 index 000000000..6fc601713 --- /dev/null +++ b/mock/cfc/mock/upload/startChunkApi.json @@ -0,0 +1,8 @@ +{ + "status": 0, + "msg": "", + "data": { + "key": "images/JSSDK_page-xxxx.zip", + "uploadId": "036f64cd5dd95750d4bcb33556b629c6" + } +} diff --git a/package.json b/package.json index 111f852e1..5447208a2 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "dependencies": { "amis-formula": "^1.3.13", "ansi-to-react": "^6.1.6", - "async": "2.6.0", "attr-accept": "2.2.2", "blueimp-canvastoblob": "2.1.0", "classnames": "2.3.1", diff --git a/src/renderers/Form/InputFile.tsx b/src/renderers/Form/InputFile.tsx index da80450cb..95c607658 100644 --- a/src/renderers/Form/InputFile.tsx +++ b/src/renderers/Form/InputFile.tsx @@ -2,8 +2,6 @@ import React from 'react'; import {FormItem, FormControlProps, FormBaseControl} from './Item'; import find from 'lodash/find'; import isPlainObject from 'lodash/isPlainObject'; -// @ts-ignore -import mapLimit from 'async/mapLimit'; import ImageControl from './InputImage'; import {Payload, ApiObject, ApiString, Action} from '../../types'; import {filter} from '../../utils/tpl'; @@ -83,6 +81,11 @@ export interface FileControlSchema extends FormBaseControl { */ chunkSize?: number; + /** + * 分块上传的并发数 + */ + concurrency?: number; + /** * 分割符 */ @@ -302,6 +305,7 @@ export default class FileControl extends React.Component { startChunkApi: '/api/upload/startChunk', chunkApi: '/api/upload/chunk', finishChunkApi: '/api/upload/finishChunk', + concurrency: 3, accept: '', multiple: false, autoUpload: true, @@ -979,6 +983,7 @@ export default class FileControl extends React.Component { onProgress: (progress: number) => void ): Promise { const chunkSize = config.chunkSize || 5 * 1024 * 1024; + const concurrency = this.props.concurrency; const self = this; let startProgress = 0.2; let endProgress = 0.9; @@ -1020,7 +1025,7 @@ export default class FileControl extends React.Component { self._send(file, startApi).then(startChunk).catch(reject); - function startChunk(ret: Payload) { + async function startChunk(ret: Payload) { onProgress(startProgress); const tasks = getTasks(file); progressArr = tasks.map(() => 0); @@ -1036,18 +1041,25 @@ export default class FileControl extends React.Component { total: tasks.length }; - mapLimit( - tasks, - 3, - uploadPartFile(state, config), - function (err: any, results: any) { - if (err) { - reject(err); - } else { - finishChunk(results, state); - } - } - ); + let results: any[] = []; + while (tasks.length) { + const res = await Promise.all( + tasks.splice(0, concurrency).map(async task => { + return await uploadPartFile(state, config)( + task, + (err: any, value: any) => { + if (err) { + reject(err); + throw new Error(err); + } + return value; + } + ); + }) + ); + results = results.concat(res); + } + finishChunk(results, state); } function updateProgress(partNumber: number, progress: number) {