最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Resolve promise into addEventListener - Stack Overflow

programmeradmin3浏览0评论

I'm actually developping a text editor and just got stuck with an issue regarding the image upload and display method.

What I'm trying to achieve

On the click of a button in the toolbar, the app displays a pop-up for uploading a picture. The user can then drag'n drop the file or click and select the file through his file system. After the image is selected, I send it to the server through ajax which uploads it and stores it in a folder. Once this is done, the server sends a response that the file is okay and ready to use. The function then resolves and the editor adds the proper link to the image.

I tried something that worked while attaching event listeners in the 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 */
  });
}

I'm actually developping a text editor and just got stuck with an issue regarding the image upload and display method.

What I'm trying to achieve

On the click of a button in the toolbar, the app displays a pop-up for uploading a picture. The user can then drag'n drop the file or click and select the file through his file system. After the image is selected, I send it to the server through ajax which uploads it and stores it in a folder. Once this is done, the server sends a response that the file is okay and ready to use. The function then resolves and the editor adds the proper link to the image.

I tried something that worked while attaching event listeners in the 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 */
  });
}

It's all good, but everytime you trigger the function, a new listener is attached and the function inside runs another time per new click...

I then thought I might remove the listeners after the promise resolves. However, in order to do so, I can't make use of anonymous functions but then I can't use my resolve method inside as it throws an error.

This is not working:

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
  }
}

I'm running out of idea...

Share Improve this question edited Jul 16, 2021 at 17:57 John Kugelman 362k69 gold badges548 silver badges594 bronze badges asked Aug 10, 2017 at 12:34 Pierre BurtonPierre Burton 2,0842 gold badges17 silver badges30 bronze badges 1
  • I can see another issue here, if popup is open and user upload and then change file or drops on dropZone two times then event will fire twice and it will try to resolve a already resolved promise in second attempt. – Manish Mittal Commented Sep 7, 2020 at 4:30
Add a comment  | 

2 Answers 2

Reset to default 13

in order to do so, I can't make use of anonymous functions but then I can't use my resolve method inside

There's no reason to move the function(s) outside of the uploadImage function or the new Promise callback when naming them or converting them to declarations:

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 */
});

ElementTarget.addEventListener() takes three arguments. The event name, a callback and an options object. Now this options object is interesting and can be handy since it includes a boolean property called once. What does it do..?

  • once: A Boolean indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.

Cool. Then you may simply change your first snippet as follows;

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 */
  });
}
发布评论

评论列表(0)

  1. 暂无评论