44. JS 應用場景(Promise => 圖片上傳)

小小魯班的技術口袋發表於2017-10-20

首發於我的github部落格, 歡迎關注

Promise

  1. Promise.reject()

    element || iview 上傳圖片尺寸校驗

    1. 在上傳圖片之前,驗證圖片大小、尺寸等資訊,可以返回一個Promise。當驗證成功的時候,可以return file。 這樣,在upload中可以拿到該檔案物件
    2. 當驗證失敗的時候,需要使用reject,因此需要使用return Promise.reject() (無法直接返回false的原因是return 的內容需要是一個Promise)
// element ui 程式碼
// https://github.com/ElemeFE/element/blob/dev/packages/upload/src/upload.vue#L77
upload(rawFile, file) {
  this.$refs.input.value = null;
  if (!this.beforeUpload) {
    return this.post(rawFile);
  }
  const before = this.beforeUpload(rawFile);
  if (before && before.then) {
    before.then(processedFile => {
      if (Object.prototype.toString.call(processedFile) === '[object File]') {
        this.post(processedFile);
      } else {
        this.post(rawFile);
      }
    }, () => {
      this.onRemove(null, rawFile);
    });
  } else if (before !== false) {
    this.post(rawFile);
  } else {
    this.onRemove(null, rawFile);
  }
},複製程式碼
// 元件關鍵實現
checkWidthHeight(file) {
    return new Promise((resolve, reject) => {
        // 取限定尺寸
        let width = this.limit.width
        let height = this.limit.height
        var _URL = window.URL || window.webkitURL;
        var img = new Image()
        img.onload = function() {
            // this => img
            let valid = width === this.width  && height === this.height
            valid ? resolve() : reject(this)
        }
        img.src = _URL.createObjectURL(file)
    })
},
handleBeforeUpload(file) {
    return this.checkWidthHeight(file).then(async () => {
        let filename = `qiniu-filename-prefix-`
        file.name.replace(/.(jpg|jpeg|png|gif)$/, (prefix, suffix) => {
            // suffix => 取檔案字尾
            // 檔名新增時間戳隨機數防止重複
            filename += `${+new Date()}${suffix}`
        })
        this.fileName = filename
        this.form.key = filename
        this.form.token = await api.qiniuUploadToken() // ajax 取七牛上傳 token
        return file // 被element upload 中的 before.then(processedFile =>  {} ) 呼叫
    }, (img) => {
        this.$Notice.warning({
            title: `檔案尺寸不正確`,
            desc: `檔案尺寸 width: ${img.width}, height: ${img.height}`
        });
        // 返回 reject
        // 從而呼叫 element upload 方法中reject 的 this.onRemove(null, rawFile);
        return Promise.reject()
    })
},複製程式碼

相關文章