@@ -10,6 +10,8 @@ let mac;
1010let originDirectoryPath ; // 源目录路径
1111let zone ;
1212let force ;
13+ let concurrencyNumber = 40 ; // 并发数
14+ const chain = [ ] ;
1315
1416const zoneMap = {
1517 huad : "Zone_z0" ,
@@ -28,15 +30,14 @@ const zoneMap = {
2830 * @param {String } fileName 文件名
2931 * @param {String } prefix 前缀
3032 */
31- function uploadFile ( filedir , fileNameIn , prefix = "" ) {
33+ function uploadFile ( filedir , fileNameIn , prefix = "" , callback ) {
3234 let fileName = prefix + fileNameIn ;
3335 const options = {
3436 scope : force ? `${ bucket } :${ fileName } ` : bucket
3537 } ;
3638 const putPolicy = new qiniu . rs . PutPolicy ( options ) ;
3739 const uploadToken = putPolicy . uploadToken ( mac ) ;
3840 const putExtra = new qiniu . form_up . PutExtra ( ) ;
39-
4041 const config = new qiniu . conf . Config ( ) ;
4142 if ( ! isEmpty ( zone ) ) {
4243 config . zone = qiniu . zone [ zoneMap [ zone ] ] ;
@@ -50,14 +51,17 @@ function uploadFile(filedir, fileNameIn, prefix = "") {
5051 respInfo
5152 ) {
5253 if ( respErr ) {
54+ log . fail ( `Upload ${ bucket } ${ fileName } fail.` ) ;
5355 log . error ( respErr ) ;
5456 }
5557 if ( respInfo . statusCode == 200 ) {
56- log . success ( `Upload ${ bucket } ${ fileName } success` ) ;
58+ log . success ( `Upload ${ bucket } ${ fileName } success.` ) ;
59+ callback ( ) ;
5760 } else {
5861 log . fail (
5962 `Upload ${ bucket } ${ fileName } fail. ${ respInfo . statusCode } ${ respBody . error } `
6063 ) ;
64+ callback ( ) ;
6165 }
6266 } ) ;
6367}
@@ -67,36 +71,38 @@ function uploadFile(filedir, fileNameIn, prefix = "") {
6771 * @param {String } filePath 初始目录
6872 */
6973function fileDisplay ( filePath ) {
70- fs . readdir ( filePath , function ( err , files ) {
71- if ( err ) {
72- log . error ( err ) ;
73- } else {
74- files . forEach ( function ( filename ) {
75- const filedir = path . join ( filePath , filename ) ;
76- fs . stat ( filedir , function ( eror , stats ) {
77- if ( eror ) {
78- log . error ( error ) ;
79- } else {
80- const isFile = stats . isFile ( ) ;
81- const isDir = stats . isDirectory ( ) ;
82- if ( isFile ) {
83- const fileName = filedir
84- . replace ( ` ${ originDirectoryPath } ${ path . sep } ` , "" )
85- . replace ( / \\ / g , "/" ) ;
86- uploadFile ( filedir , fileName , prefix ) ;
87- } else if ( isDir ) {
88- fileDisplay ( filedir ) ;
89- }
90- }
91- } ) ;
92- } ) ;
93- }
94- } ) ;
74+ try {
75+ const files = fs . readdirSync ( filePath ) ;
76+ files . forEach ( function ( filename ) {
77+ const filedir = path . join ( filePath , filename ) ;
78+ try {
79+ const stats = fs . statSync ( filedir ) ;
80+ const isFile = stats . isFile ( ) ;
81+ const isDir = stats . isDirectory ( ) ;
82+ if ( isFile ) {
83+ const fileName = filedir
84+ . replace ( ` ${ originDirectoryPath } ${ path . sep } ` , "" )
85+ . replace ( / \\ / g , "/" ) ;
86+ chain . push ( ( ... args ) =>
87+ uploadFile ( filedir , fileName , prefix , ... args )
88+ ) ;
89+ } else if ( isDir ) {
90+ fileDisplay ( filedir ) ;
91+ }
92+ } catch ( error ) {
93+ log . error ( error ) ;
94+ }
95+ } ) ;
96+ } catch ( error ) {
97+ log . error ( error ) ;
98+ }
9599}
96100
97101function upload ( program ) {
98102 const accessKey = program . accessKey ;
99103 const secretKey = program . secretKey ;
104+ const pConcurrencyNumber = Number ( program . concurrencyNumber ) ;
105+
100106 bucket = program . bucket ;
101107 prefix = isEmpty ( program . prefix ) ? "" : program . prefix ;
102108 force = ! ! program . force ;
@@ -109,12 +115,59 @@ function upload(program) {
109115 ) ;
110116 }
111117
118+ if ( Number . isInteger ( pConcurrencyNumber ) ) {
119+ concurrencyNumber = pConcurrencyNumber ;
120+ }
121+
112122 originDirectoryPath = path . resolve (
113123 ! isEmpty ( program . originDirectoryPath )
114124 ? program . originDirectoryPath . replace ( / \\ / g, "/" )
115125 : "dist"
116126 ) ;
117127 fileDisplay ( originDirectoryPath ) ;
128+ batchExec ( chain , successCallback ) ;
129+ }
130+
131+ /**
132+ * 成功回调
133+ * @param {Number } length
134+ */
135+ function successCallback ( length ) {
136+ log . success ( `Done, all ${ length } files upload success.` ) ;
137+ }
138+
139+ /**
140+ *
141+ * @param {Array } chain 执行队列
142+ */
143+ async function batchExec ( chain , callback ) {
144+ const chainLen = chain . length ;
145+ const promises = { } ;
146+ let diff ;
147+ let promisesLen ;
148+ let promiseKey ;
149+ let startNum = 0 ;
150+ let timer = setInterval ( ( ) => {
151+ if ( chain . length === 0 ) {
152+ clearInterval ( timer ) ;
153+ timer = null ;
154+ return ;
155+ }
156+ diff = concurrencyNumber - Object . keys ( promises ) . length ;
157+ if ( diff <= 0 ) return ;
158+ chain . splice ( 0 , diff ) . forEach ( fn => {
159+ promiseKey = startNum ++ ;
160+ promises [ promiseKey ] = true ;
161+ ( function ( promiseKey ) {
162+ fn ( ( ) => {
163+ delete promises [ promiseKey ] ;
164+ if ( Object . keys ( promises ) . length === 0 ) {
165+ callback ( chainLen ) ;
166+ }
167+ } ) ;
168+ } ) ( promiseKey ) ;
169+ } ) ;
170+ } , 0 ) ;
118171}
119172
120173module . exports = upload ;
0 commit comments