Reputation: 1800
In JS, I would like to:
Something like this:
function my_func() {
// This creates an empty promise.
const p = Promise;
// When a user clicks a button in UI then we resolve the promise.
// This would be in an event!
// p.resolve('user clicked OK');
// Returns empty promise.
return p;
}
function main() {
// Here when the promise is resolved then we get the value.
my_func().then(function(v) {
console.log(v);
});
}
Upvotes: 1
Views: 2716
Reputation: 1800
Found answers here: Creating a (ES6) promise without starting to resolve it
deferreds
can be passed around as I want and then the promise can be resolved or rejected somewhere else.
Haven't tested this in code yet, so don't know if there's any problem with this approach.
function my_func() {
const deferreds = [];
const p = new Promise(function (resolve, reject) {
deferreds.push({ resolve: resolve, reject: reject });
});
const btn = document.querySelector('.btn');
btn.addEventListener('click', event => {
deferreds[0].resolve('User clicked button!');
}, {once: true});
return p;
}
function main() {
my_func().then(function (v) {
console.log(v);
});
}
main();
<button class="btn">
Hi! Click me
</button>
Upvotes: 3
Reputation: 135197
It seems like an odd design, but as Bergi comments, there's nothing stopping you from doing it -
function my_func () {
return new Promise(r =>
document.forms.myapp.mybutton.onclick = r
)
}
function main () {
my_func().then(event => console.log(event.target))
}
main()
<form id="myapp">
<button type="button" name="mybutton">Click me</button>
</form>
A Promise can be resolved a maximum of one time, so it probably makes sense to automatically remove the event listener after the first click. We could rename my_func
to onclick
and give it a parameter to make it reusable -
function onclick(elem) {
return new Promise(r =>
elem.addEventListener("click", r, {once: true})
)
}
function main () {
onclick(document.forms.myapp.mybutton)
.then(event => console.log(event.target))
onclick(document.forms.myapp.otherbutton)
.then(event => console.log(event.target))
}
main()
<form id="myapp">
<button type="button" name="mybutton">A</button>
<button type="button" name="otherbutton">B</button>
</form>
Now onclick
can be used in more interesting ways. For example, we could make a button that needs two clicks before the effect is triggered -
function onclick(elem) {
return new Promise(r =>
elem.addEventListener("click", r, {once: true})
)
}
function main () {
onclick(document.forms.myapp.mybutton)
.then(event => console.log(event.target))
onclick(document.forms.myapp.otherbutton)
.then(_ =>
onclick(document.forms.myapp.otherbutton)
.then(event => console.log(event.target))
)
}
main()
<form id="myapp">
<button type="button" name="mybutton">click once</button>
<button type="button" name="otherbutton">click twice</button>
</form>
Upvotes: 1