src/advance.js
function uploadSliceList(params, cb) {
    var self = this;
    var TaskId = params.TaskId;
    var Bucket = params.Bucket;
    var Region = params.Region;
    var Key = params.Key;
    var UploadData = params.UploadData;
    var FileSize = params.FileSize;
    var SliceSize = params.SliceSize;
    var ChunkParallel = Math.min(params.AsyncLimit || self.options.ChunkParallelLimit || 1, 256);
    var Body = params.Body;
    var SliceCount = Math.ceil(FileSize / SliceSize);
    var FinishSize = 0;
    var ServerSideEncryption = params.ServerSideEncryption;
    var needUploadSlices = util.filter(UploadData.PartList, function (SliceItem) {
        if (SliceItem['Uploaded']) {
            FinishSize += SliceItem['PartNumber'] >= SliceCount ? (FileSize % SliceSize || SliceSize) : SliceSize;
        }
        return !SliceItem['Uploaded'];
    });
    var onProgress = params.onProgress;

    Async.eachLimit(needUploadSlices, ChunkParallel, function (SliceItem, asyncCallback) {
        if (!self._isRunningTask(TaskId)) return;
        var PartNumber = SliceItem['PartNumber'];
        var currentSize = Math.min(FileSize, SliceItem['PartNumber'] * SliceSize) - (SliceItem['PartNumber'] - 1) * SliceSize;
        var preAddSize = 0;
        uploadSliceItem.call(self, {
            TaskId: TaskId,
            Bucket: Bucket,
            Region: Region,
            Key: Key,
            SliceSize: SliceSize,
            FileSize: FileSize,
            PartNumber: PartNumber,
            ServerSideEncryption: ServerSideEncryption,
            Body: Body,
            UploadData: UploadData,
            onProgress: function (data) {
                FinishSize += data.loaded - preAddSize;
                preAddSize = data.loaded;
                onProgress({loaded: FinishSize, total: FileSize});
            },
        }, function (err, data) {
            if (!self._isRunningTask(TaskId)) return;
            if (util.isBrowser && !err && !data.ETag) {
                err = 'get ETag error, please add "ETag" to CORS ExposeHeader setting.';
            }
            if (err) {
                FinishSize -= preAddSize;
            } else {
                FinishSize += currentSize - preAddSize;
                SliceItem.ETag = data.ETag;
            }
            asyncCallback(err || null, data);
        });
    }, function (err) {
        if (!self._isRunningTask(TaskId)) return;
        if (err)  return cb(err);
        cb(null, {
            UploadId: UploadData.UploadId,
            SliceList: UploadData.PartList
        });
    });
}
function uploadSliceList(params, cb) {
    var self = this;
    var TaskId = params.TaskId;
    var Bucket = params.Bucket;
    var Region = params.Region;
    var Key = params.Key;
    var UploadData = params.UploadData;
    var FileSize = params.FileSize;
    var SliceSize = params.SliceSize;
    var ChunkParallel = Math.min(params.AsyncLimit || self.options.ChunkParallelLimit || 1, 256);
    var Body = params.Body;
    var SliceCount = Math.ceil(FileSize / SliceSize);
    var FinishSize = 0;
    var ServerSideEncryption = params.ServerSideEncryption;
    var needUploadSlices = util.filter(UploadData.PartList, function (SliceItem) {
        if (SliceItem['Uploaded']) {
            FinishSize += SliceItem['PartNumber'] >= SliceCount ? (FileSize % SliceSize || SliceSize) : SliceSize;
        }
        return !SliceItem['Uploaded'];
    });
    var onProgress = params.onProgress;

    Async.eachLimit(needUploadSlices, ChunkParallel, function (SliceItem, asyncCallback) {
        if (!self._isRunningTask(TaskId)) return;
        var PartNumber = SliceItem['PartNumber'];
        var currentSize = Math.min(FileSize, SliceItem['PartNumber'] * SliceSize) - (SliceItem['PartNumber'] - 1) * SliceSize;
        var preAddSize = 0;
        uploadSliceItem.call(self, {
            TaskId: TaskId,
            Bucket: Bucket,
            Region: Region,
            Key: Key,
            SliceSize: SliceSize,
            FileSize: FileSize,
            PartNumber: PartNumber,
            ServerSideEncryption: ServerSideEncryption,
            Body: Body,
            UploadData: UploadData,
            onProgress: function (data) {
                FinishSize += data.loaded - preAddSize;
                preAddSize = data.loaded;
                onProgress({loaded: FinishSize, total: FileSize});
            },
        }, function (err, data) {
            if (!self._isRunningTask(TaskId)) return;
            if (util.isBrowser && !err && !data.ETag) {
                err = 'get ETag error, please add "ETag" to CORS ExposeHeader setting.';
            }
            if (err) {
                FinishSize -= preAddSize;
            } else {
                FinishSize += currentSize - preAddSize;
                SliceItem.ETag = data.ETag;
            }
            asyncCallback(err || null, data);
        });
    }, function (err) {
        if (!self._isRunningTask(TaskId)) return;
        if (err)  return cb(err);
        cb(null, {
            UploadId: UploadData.UploadId,
            SliceList: UploadData.PartList
        });
    });
}
function uploadSliceList ( params , cb ) { var self = this ; var TaskId = params . TaskId ; var Bucket = params . Bucket ; var Region = params . Region ; var Key = params . Key ; var UploadData = params . UploadData ; var FileSize = params . FileSize ; var SliceSize = params . SliceSize ; var ChunkParallel = Math . min ( params . AsyncLimit || self . options . ChunkParallelLimit || 1 , 256 ) ; var Body = params . Body ; var SliceCount = Math . ceil ( FileSize / SliceSize ) ; var FinishSize = 0 ; var ServerSideEncryption = params . ServerSideEncryption ; var needUploadSlices = util . filter ( UploadData . PartList , function ( SliceItem ) { if ( SliceItem [ 'Uploaded' ] ) { FinishSize += SliceItem [ 'PartNumber' ] >= SliceCount ? ( FileSize % SliceSize || SliceSize ) : SliceSize ; } return ! SliceItem [ 'Uploaded' ] ; } ) ; var onProgress = params . onProgress ; Async . eachLimit ( needUploadSlices , ChunkParallel , function ( SliceItem , asyncCallback ) { if ( ! self . _isRunningTask ( TaskId ) ) return ; var PartNumber = SliceItem [ 'PartNumber' ] ; var currentSize = Math . min ( FileSize , SliceItem [ 'PartNumber' ] * SliceSize ) - ( SliceItem [ 'PartNumber' ] - 1 ) * SliceSize ; var preAddSize = 0 ; uploadSliceItem . call ( self , { TaskId : TaskId , Bucket : Bucket , Region : Region , Key : Key , SliceSize : SliceSize , FileSize : FileSize , PartNumber : PartNumber , ServerSideEncryption : ServerSideEncryption , Body : Body , UploadData : UploadData , onProgress : function ( data ) { FinishSize += data . loaded - preAddSize ; preAddSize = data . loaded ; onProgress ( { loaded : FinishSize , total : FileSize } ) ; } , } , function ( err , data ) { if ( ! self . _isRunningTask ( TaskId ) ) return ; if ( util . isBrowser && ! err && ! data . ETag ) { err = 'get ETag error, please add "ETag" to CORS ExposeHeader setting.' ; } if ( err ) { FinishSize -= preAddSize ; } else { FinishSize += currentSize - preAddSize ; SliceItem . ETag = data . ETag ; } asyncCallback ( err || null , data ) ; } ) ; } , function ( err ) { if ( ! self . _isRunningTask ( TaskId ) ) return ; if ( err ) return cb ( err ) ; cb ( null , { UploadId : UploadData . UploadId , SliceList : UploadData . PartList } ) ; } ) ; }
上传文件分块，包括 /*
UploadId (上传任务编号)
AsyncLimit (并发量)，
SliceList (上传的分块数组)，
FilePath (本地文件的位置)，
SliceSize (文件分块大小)
FileSize (文件大小)
onProgress (上传成功之后的回调函数)
上传文件分块，包括 / * UploadId ( 上传任务编号 ) AsyncLimit ( 并发量 ) ， SliceList ( 上传的分块数组 ) ， FilePath ( 本地文件的位置 ) ， SliceSize ( 文件分块大小 ) FileSize ( 文件大小 ) onProgress ( 上传成功之后的回调函数 )