将promise转换为addEventListener

时间:2017-08-10 12:34:18

标签: javascript promise

我实际上正在开发一个文本编辑器,并且遇到了有关图像上传和显示方法的问题。

  

我想要实现的目标

     

单击工具栏中的按钮,应用程序会显示弹出窗口   上传图片。然后,用户可以拖放文件或单击   并通过他的文件系统选择文件。在图像之后   选中,我通过上传它的ajax将其发送到服务器   将其存储在一个文件夹中。完成此操作后,服务器会发送响应   该文件是好的,准备好使用。该功能然后解决和   编辑器会在图像中添加正确的链接。

我尝试了在promise中附加事件监听器时有效的方法。

function uploadImage(editor) {
  /* Displays the pop-up */
  uploadView.style.display = "block";

  var promise = new Promise(function(resolve, reject) {

    uploadInput.addEventListener('change', function(event) {
      /* ajax call */
      resolve(value);
    });
    dropZone.addEventListener('drop', function(event) {
      /* ajax call */
      resolve(value);
    });

  });

  promise.then(function(result) {
    /* Adds the link */
  }, function(err) {
    /* handles errors */
  });
}

这一切都很好,但是每当你触发这个函数时,都会附加一个新的监听器,并且每次新点击时内部函数会运行另一次......

然后我想我可能会在promise解决后删除侦听器。但是,为了做到这一点,我不能使用匿名函数,但是我不能在里面使用我的resolve方法,因为它会抛出错误。

这不起作用:

function uploadImage(editor) {
  /* Displays the pop-up */
  uploadView.style.display = "block";

  var promise = new Promise(function(resolve, reject) {

    uploadInput.addEventListener('change', handleUpload);
    dropZone.addEventListener('drop', handleUpload);

  });

  promise.then(function(result) {
    /* Adds the link */
    /* Removes the listeners */
    uploadInput.removeEventListener('change', handleUpload);
    dropZone.removeEventListener('drop', handleUpload);

  }, function(err) {
    /* Handles errors */
    /* Removes the listeners */
    uploadInput.removeEventListener('change', handleUpload);
    dropZone.removeEventListener('drop', handleUpload);
  });
}

function handleUpload(event) {
  if (event.type == "change") {
    /* ajax call */
    resolve(value); // Throws an error
  } else {
    /* ajax call */
    resolve(value); // Throws an error
  }
}

我已经没想完了......

2 个答案:

答案 0 :(得分:6)

  

为了做到这一点,我无法使用匿名功能但是我无法在里面使用我的解决方法

在命名或将它们转换为声明时,没有理由将函数移到uploadImage函数或new Promise回调之外:

var promise = new Promise(function(resolve, reject) {
  function handleUpload(event) {
    /* Removes the listeners */
    uploadInput.removeEventListener('change', handleUpload);
    dropZone.removeEventListener('drop', handleUpload);
    resolve(event); // works just fine
  }
  uploadInput.addEventListener('change', handleUpload);
  dropZone.addEventListener('drop', handleUpload);
});

promise.then(function(event) {
  if (event.type == "change") {
    return /* ajax call */
  } else {
    return /* other ajax call */
  }
}).then(function(result) {
  /* Adds the link */
}, function(err) {
  /* Handles errors */
});

答案 1 :(得分:2)

ElementTarget.addEventListener()有三个参数。事件名称,回调和选项对象。现在这个选项对象很有趣,并且可以很方便,因为它包含一个名为once的布尔属性。它做了什么..?

  • once:一个布尔值,表示在添加后最多应调用一次监听器。如果为true,则在调用时将自动删除侦听器。

冷却。然后,您可以按如下方式更改第一个代码段;

function uploadImage(editor) {
  /* Displays the pop-up */
  uploadView.style.display = "block";

  var promise = new Promise(function(resolve, reject) {

    uploadInput.addEventListener('change', function(event) {
      /* ajax call */
      resolve(value);
    },{once: true}); // remove event after run once
    dropZone.addEventListener('drop', function(event) {
      /* ajax call */
      resolve(value);
    },{once: true}); // remove event after run once

  });

  promise.then(function(result) {
    /* Adds the link */
  }, function(err) {
    /* handles errors */
  });
}