@@ -10,6 +10,8 @@ let mac;
10
10
let originDirectoryPath ; // 源目录路径
11
11
let zone ;
12
12
let force ;
13
+ let concurrencyNumber = 40 ; // 并发数
14
+ const chain = [ ] ;
13
15
14
16
const zoneMap = {
15
17
huad : "Zone_z0" ,
@@ -28,15 +30,14 @@ const zoneMap = {
28
30
* @param {String } fileName 文件名
29
31
* @param {String } prefix 前缀
30
32
*/
31
- function uploadFile ( filedir , fileNameIn , prefix = "" ) {
33
+ function uploadFile ( filedir , fileNameIn , prefix = "" , callback ) {
32
34
let fileName = prefix + fileNameIn ;
33
35
const options = {
34
36
scope : force ? `${ bucket } :${ fileName } ` : bucket
35
37
} ;
36
38
const putPolicy = new qiniu . rs . PutPolicy ( options ) ;
37
39
const uploadToken = putPolicy . uploadToken ( mac ) ;
38
40
const putExtra = new qiniu . form_up . PutExtra ( ) ;
39
-
40
41
const config = new qiniu . conf . Config ( ) ;
41
42
if ( ! isEmpty ( zone ) ) {
42
43
config . zone = qiniu . zone [ zoneMap [ zone ] ] ;
@@ -50,14 +51,17 @@ function uploadFile(filedir, fileNameIn, prefix = "") {
50
51
respInfo
51
52
) {
52
53
if ( respErr ) {
54
+ log . fail ( `Upload ${ bucket } ${ fileName } fail.` ) ;
53
55
log . error ( respErr ) ;
54
56
}
55
57
if ( respInfo . statusCode == 200 ) {
56
- log . success ( `Upload ${ bucket } ${ fileName } success` ) ;
58
+ log . success ( `Upload ${ bucket } ${ fileName } success.` ) ;
59
+ callback ( ) ;
57
60
} else {
58
61
log . fail (
59
62
`Upload ${ bucket } ${ fileName } fail. ${ respInfo . statusCode } ${ respBody . error } `
60
63
) ;
64
+ callback ( ) ;
61
65
}
62
66
} ) ;
63
67
}
@@ -67,36 +71,38 @@ function uploadFile(filedir, fileNameIn, prefix = "") {
67
71
* @param {String } filePath 初始目录
68
72
*/
69
73
function 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
+ }
95
99
}
96
100
97
101
function upload ( program ) {
98
102
const accessKey = program . accessKey ;
99
103
const secretKey = program . secretKey ;
104
+ const pConcurrencyNumber = Number ( program . concurrencyNumber ) ;
105
+
100
106
bucket = program . bucket ;
101
107
prefix = isEmpty ( program . prefix ) ? "" : program . prefix ;
102
108
force = ! ! program . force ;
@@ -109,12 +115,59 @@ function upload(program) {
109
115
) ;
110
116
}
111
117
118
+ if ( Number . isInteger ( pConcurrencyNumber ) ) {
119
+ concurrencyNumber = pConcurrencyNumber ;
120
+ }
121
+
112
122
originDirectoryPath = path . resolve (
113
123
! isEmpty ( program . originDirectoryPath )
114
124
? program . originDirectoryPath . replace ( / \\ / g, "/" )
115
125
: "dist"
116
126
) ;
117
127
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 ) ;
118
171
}
119
172
120
173
module . exports = upload ;
0 commit comments