美文网首页
我处理过的异步问题

我处理过的异步问题

作者: 方_糖 | 来源:发表于2019-07-12 12:46 被阅读0次

此文仅记录我工作时遇到异步问题的解决办法。

问题一:

在使用dropzone为上传插件时,当设置autoProcessQueue: true就会自动上传,
上传之前会有一个sending函数来处理formData。代码如下

var myDropzone = new Dropzone("#myId", {
          paramName: "file",
          autoProcessQueue: true,
          url: "<c:url value='/uploadFile.htm'><c:param name='methodToCall' value='submitNewDocumentForm2' /></c:url>",
          sending: function (file, xhr, formData) {
            formData.append("formFile", file);
            formData.append("filenames", file.name);
            if (file.size > 0) {
              EXIF.getData(file,function () {
                exifData = JSON.stringify(file.exifdata);
                formData.append("exif", exifData);
                console.log(exifData)
              })
            } else {
              exifData = "";
            }
          },
          ....
}

但是此时我使用的EXIF.getData为一个异步的回调函数,也就是说在还没有执行formData.append("exif", exifData);之前,formData就已经被上传了。所以我现在想让formData.append("exif", exifData);执行后再去执行上传代码。
由于dropzone的上传代码并不能在当前页面显示,所以我要去dropzone.js找到上传代码。ps : 其实只需要找到ajax的send函数就可以了

Dropzone.prototype.submitRequest = function(xhr, formData, files) {
      return xhr.send(formData);
    };

于是我就顺着找到了submitRequest函数,这个函数就是处理在upload之前发生的所有事件,具体就不看了,主要看在哪里包装了formData

Dropzone.prototype.uploadFiles = function(files) {
      var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
     ....此处省略很多行.....
      formData = new FormData();
      if (this.options.params) {
        _ref1 = this.options.params;
        for (key in _ref1) {
          value = _ref1[key];
          formData.append(key, value);
        }
      }
      for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
        file = files[_j];
        this.emit("sending", file, xhr, formData);
      }
      if (this.options.uploadMultiple) {
        this.emit("sendingmultiple", files, xhr, formData);
      }
      if (this.element.tagName === "FORM") {
        _ref2 = this.element.querySelectorAll("input, textarea, select, button");
        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
          input = _ref2[_k];
          inputName = input.getAttribute("name");
          inputType = input.getAttribute("type");
          if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
            _ref3 = input.options;
            for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
              option = _ref3[_l];
              if (option.selected) {
                formData.append(inputName, option.value);
              }
            }
          } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
            formData.append(inputName, input.value);
          }
        }
      }
      for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {
        formData.append(this._getParamName(i), files[i], this._renameFilename(files[i].name));
      }
      return this.submitRequest(xhr, formData, files);
   }

所以我们只需要在return this.submitRequest(xhr, formData, files);之前让formData有完整的数据就完美了
所以怎么办呢?

解决办法:

使用promise,具体代码如下:

Dropzone.prototype.uploadFiles = function(files) {

        var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
        ....此处省略很多行.....
        var that=this;
        var promise=new Promise(function(resolve,reject){
        formData = new FormData();
        if (that.options.params) {
          _ref1 = that.options.params;
          for (key in _ref1) {
            value = _ref1[key];
            formData.append(key, value);
          }
        }
          for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
            file = files[_j];
            that.emit("sending", file, xhr, formData);
          }
          if (that.options.uploadMultiple) {
            that.emit("sendingmultiple", files, xhr, formData);
          }
          if (that.element.tagName === "FORM") {
            _ref2 = that.element.querySelectorAll("input, textarea, select, button");
            for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
              input = _ref2[_k];
              inputName = input.getAttribute("name");
              inputType = input.getAttribute("type");
              if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
                _ref3 = input.options;
                for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
                  option = _ref3[_l];
                  if (option.selected) {
                    formData.append(inputName, option.value);
                  }
                }
              } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) {
                formData.append(inputName, input.value);
              }
            }
          }
          for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) {
            formData.append(that._getParamName(i), files[i], that._renameFilename(files[i].name));
          }
          console.log(formData.get("filenames"));
          var timer=setInterval(function(){
            if(formData.get("exif")!=null){
              clearInterval(timer)
              resolve();
            }
          },100)

      });
      promise.then(function() {
        return that.submitRequest(xhr, formData, files);
      },function(error){
        console.log(error)
      });
    };

其实就是把处理formData的代码放入promise中,等他们全部执行完成后,通过if(formData.get("exif")!=null)判断formData.append("exif", exifData);有没有执行,执行完之后才让他上传。

处理中遇到的问题
1.在用promise()包装中的代码,很多都会报出undefined。原因是此时的this会发生变化,所以我凭借以前微信小程序的经验使用var that=this并且把在promise和then里面的this全用that代替。效果果然很好,哈哈哈。

相关文章

  • 我处理过的异步问题

    此文仅记录我工作时遇到异步问题的解决办法。 问题一: 在使用dropzone为上传插件时,当设置autoProce...

  • TCP之再谈解决服务器TIMEWAIT过多的问题(转)

    原文地址 这个问题在网上已经有很多人讨论过了,再谈这个问题,只是根据我处理过的相关业务来谈谈我的看法。至于什么是T...

  • 结了婚,女人们都得牢记这5个忠告

    从事情感咨询行业以来,我处理过不少在亲密关系中的问题,经常有人问道: “老师,以前我们感情很好,为什么他现在对我那...

  • Java异步处理

    同步与异步通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线...

  • SpringMVC之异步分析Callable,WebAsyncT

    1 SpringMVC异步 1.1 引言 spring mvc同步接口在请求处理过程中一直处于阻塞状态,而异步接口...

  • 说散就散的感情,究竟做错了什么?

    作为值乎平台上回答总数最多的答主, 我处理过各式各样的情感问题, 这其中有些题主的遭遇,或者说他们经历过的情感痛苦...

  • 文集序

    用于记录处理过 ubuntu 问题 用于记录处理过 windows 问题 用于记录处理过手机操作系统问题 用于记录...

  • 我处于问题区了

    娃现在还没有睡,我的简书还没有更新,所以我处于问题区,所以女儿喝水把衣服,床弄湿了,我发了脾气,给女儿换了衣服...

  • filterChain

    WebAsyncManagerIntegrationFilter 为请求处理过程中可能发生的异步调用准备安全上下文...

  • 处理过的问题总结

    解决问题: 1 如何消除img间的默认间隙2 添加网站ico图标3 DIV+CSS让同一行的图片和文字对齐4 去掉...

网友评论

      本文标题:我处理过的异步问题

      本文链接:https://www.haomeiwen.com/subject/fljekctx.html