44. JS 应用场景(Promise => 图片上传)

3,116 阅读1分钟

首发于我的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()
    })
},