EDIT: tried to clarify the question and shorten it -- I'd put in some code to show I had tried to solve this, but I think it only confused things.
I'm a Promise newbie and I am trying to convert some existing code (which is quite simple) to work with promises.
I'd like to link a button click to other parts of my program using promises, that is I'd like to treat the click as the asynchronous event (akin to an ajax call, for example). How does one do this?
From the MDN documentation, a promise basically works like this
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
and I understand that perfectly. To my understanding the following would work
function myPromiseGenerator() {
return new Promise((resolve, reject) => {
this.myButton.addEventListener('click',function(e) {
/// do something to process the answer
resolve(something);
}
});
}
but then how do I remove the event listener? I'd like to add the event listener only once, not in each call to myPromiseGenerator
but I can't figure out how to make it work.
In general, what's the best method to do what I'm trying to do? Thanks for any help.
EDIT: tried to clarify the question and shorten it -- I'd put in some code to show I had tried to solve this, but I think it only confused things.
I'm a Promise newbie and I am trying to convert some existing code (which is quite simple) to work with promises.
I'd like to link a button click to other parts of my program using promises, that is I'd like to treat the click as the asynchronous event (akin to an ajax call, for example). How does one do this?
From the MDN documentation, a promise basically works like this
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
and I understand that perfectly. To my understanding the following would work
function myPromiseGenerator() {
return new Promise((resolve, reject) => {
this.myButton.addEventListener('click',function(e) {
/// do something to process the answer
resolve(something);
}
});
}
but then how do I remove the event listener? I'd like to add the event listener only once, not in each call to myPromiseGenerator
but I can't figure out how to make it work.
In general, what's the best method to do what I'm trying to do? Thanks for any help.
Share Improve this question edited Jun 23, 2018 at 13:28 Cerulean asked Jun 23, 2018 at 12:42 CeruleanCerulean 5432 gold badges7 silver badges17 bronze badges 6- Not very clear what you are trying to acplish or what the higher level problem you are trying to solve actually is – charlietfl Commented Jun 23, 2018 at 12:59
- If I have a single button which on click should direct to any number of different functions based on the current program state, is there a way to use promises to facilitate that? My thought was to create a function that returns a promise, in which the asynchronous event that causes the resolve to be called is the button click. The receiver of the promise determines, based on program state, what to call next by passing that to promise's then. My question is do I have to ´addEventListener´ in the promise generator function? I'd prefer to add it once, not each time that function called. – Cerulean Commented Jun 23, 2018 at 13:19
- Thinking just seems backwards. Can't you just check state within one listener and respond accordingly? – charlietfl Commented Jun 23, 2018 at 13:57
- 1 The original way I did it was to store the next function to call to which the event dispatcher -- which was linked to the button -- had access to. Click the button --> event dispatcher called --> stored function called. Worked perfectly, but I wanted to see if it could be done using promises -- to me a mouse click is an async event, just like waiting on a network response, so it seemed to fit... – Cerulean Commented Jun 23, 2018 at 14:15
-
1
Note that Promises are useful for async events that happen once per Promise.
waitForNextClick
makes sense as a Promise name becausenextClick
is a single event, buteveryClick
doesn't make much sense as a Promise since Promises can only resolve once. If you want to do something every time an async event occurs it is often better to just use callbacks. There are many places where callbacks are still useful even though we have Promises too. Anything that uses a subscribe pattern like EventEmitters or pub/sub, necessarily uses callbacks. – Paul Commented Jun 23, 2018 at 14:25
2 Answers
Reset to default 10Just use the once
option of an event listener:
function myPromiseGenerator() {
return new Promise((resolve, reject) => {
this.myButton.addEventListener('click',function(e) {
/// do something to process the answer
resolve(something);
}, {once: true});
});
}
You can do what you originally intended to do - remove the event listener - if you give the anonymous handler function a name:
async function myPromiseGenerator() {
return new Promise(resolve => {
this.myButton.addEventListener('click',
async function handler(event) {
this.myButton.removeEventListener('click', handler);
// Assume a login code has been entered - validate it
if (await validateAccessCode())
resolve(true)
else
resolve(false);
});
});
}