JS使用promises上传文件

时间:2018-02-28 10:47:21

标签: javascript

我正在构建一个分块文件上传器。我知道承诺是处理结果的最佳方式,但仍然可以解释我应该如何从外部捕获承诺。

caller.js

let fileUploader = new ChunkedUpload()
    fileUploader.setFile(file)
    fileUploader.upload().then(result => {
       // Here I'd like to catch the current result of the file
       // If it's not uploaded, I need the percentage and continue 
       // If it is I need the response from the API
       console.log(result)
    })

uploader.js

upload() {
    let totalChunks = Math.ceil(this._file.size/this._sliceSize)

    return this._chunk(0, 0, totalChunks)
}

_chunk(start, chunk, totalChunks) {
    let lastChunk = false
    let end = start + this._sliceSize

    if (this._file.size - end < 0) {
        end = this._file.size
        lastChunk = true
    }

    let slice = this._sliceFile(this._file, start, end)

    let formData = new FormData()
    formData.append('chunk', chunk)
    formData.append('chunks', totalChunks)
    formData.append('file', slice)

    return new Promise((resolve, reject) => {
        axios.post(this._url, formData).then(response => {
            if (lastChunk) {
                // This part is okay, it returns the result
                resolve({
                    uploaded: true,
                    url: response.data,
                    uploadPercentage: 100,
                    uploadSize: this.formatBytes(file.size)
                });

            } else {
                // Here's the issue. Next chunk upload is called, 
                // however I cannot track the process in caller.js
                resolve(this._chunk(
                    start += this._sliceSize,
                    chunk += 1,
                    totalChunks
                ));
            }
        })
    })
}

我接受任何评论。也许我的方法有误,请告诉我!

2 个答案:

答案 0 :(得分:1)

Promise应该用于一次性回调 - 成功或错误。

你想要的是“进步”信息。

你应该这样:

  • 使用回调函数来获取有关进度的详细信息;或
  • 聆听并发出事件;

但是,如果您真的想使用承诺而不使用回调或事件,我建议:

返回带有详细信息的promise和一个名为continue()的内部方法,该方法被调用以便进程可以继续。

下面我给你代码:

<强> caller.js

let fileUploader = new ChunkedUpload()
    fileUploader.setFile(file)
    var callback = result => {
       // Here I'd like to catch the current result of the file
       // If it's not uploaded, I need the percentage and continue 
       // If it is I need the response from the API
       console.log(result);
       if (result.uploaded) {
           console.log('DONE');
       } else {
           console.log('STILL UPLOADING...');
           result.continue()
               .then(callback);
       }
    }
    fileUploader.upload().then(callback);

<强> uploader.js

upload() {
    let totalChunks = Math.ceil(this._file.size/this._sliceSize)

    return this._chunk(0, 0, totalChunks)
}

_chunk(start, chunk, totalChunks) {
    let lastChunk = false
    let end = start + this._sliceSize

    if (this._file.size - end < 0) {
        end = this._file.size
        lastChunk = true
    }

    let slice = this._sliceFile(this._file, start, end)

    let formData = new FormData()
    formData.append('chunk', chunk)
    formData.append('chunks', totalChunks)
    formData.append('file', slice)

    return new Promise((resolve, reject) => {
        axios.post(this._url, formData).then(response => {
            if (lastChunk) {
                // This part is okay, it returns the result
                resolve({
                    uploaded: true,
                    url: response.data,
                    uploadPercentage: 100,
                    uploadSize: this.formatBytes(file.size)
                });

            } else {
                // Here's the issue. Next chunk upload is called, 
                // however I cannot track the process in caller.js
                // you may include in the object below the metrics you need
                resolve({
                    uploaded: false,
                    continue: () => {
                      return this._chunk(
                          start += this._sliceSize,
                          chunk += 1,
                          totalChunks
                    }
                });
            }
        })
    })
}

答案 1 :(得分:0)

谢谢@Rafel!你的回答让我参加了活动。

显然我被@Bergi提到的Promise构造反模式陷入了攻击并且捕获拒绝会导致另一个变量定义。

谢谢大家!