问题
I have written a pretty simply script:
{
waiting: false,
async handleWaiting(promise, timeout) {
return new Promise((res, rej) => {
let loadingStarted = false;
const timeoutInstance = setTimeout(() => {
loadingStarted = true;
this.waiting = true;
}, timeout);
const onFinished = () => {
if (loadingStarted) {
this.waiting = false;
}
clearTimeout(timeoutInstance);
}
promise
.then((result) => {
onFinished();
res(result);
})
.catch((ex) => {
onFinished();
rej(ex);
});
});
},
async searchForTerm(term) {
this.results = await this.handleWaiting(this.$wire.query(term), 500);
// do something with the results...
},
}
It tiggers the waiting spinner for a search field.
Someone wrote me, that:
Your code has the Explicit Promise construction antipattern! You should use chaining and promise composition instead... Also, a function that returns a promise, but doesn't await anything don't have to be async
I tinkered around with this working code. But I got just error over error!
Can someone help me with this, or at least put me on the right track.
I am not that good with javascript but I am interested in writing it better.
回答1:
See What is the explicit promise construction antipattern and how do I avoid it? for details. Generally speaking, you (mostly) do not need new Promise
when you already have a promise. You can just reuse the existing one (and chain it if necessary).
Your code can be simplied.
- Remove the unnecessary
new Promise
- Reuse and return the existing promise
- Remove code duplication and use
Promise#finally
instead
{
waiting: false,
handleWaiting(promise, timeout) {
let loadingStarted = false;
const timeoutInstance = setTimeout(() => {
loadingStarted = true;
this.waiting = true;
}, timeout);
return promise.finally(() => {
if (loadingStarted) {
this.waiting = false;
}
clearTimeout(timeoutInstance);
});
},
async searchForTerm(term) {
this.results = await this.handleWaiting(this.$wire.query(term), 500);
// do something with the results...
},
}
And you can probably get rid of loadingStarted
as well. Is there a reason why you have two state variables for that? You never reset loadingStarted
anyway.
{
waiting: false,
handleWaiting(promise, timeout) {
const timeoutInstance = setTimeout(() => {
this.waiting = true;
}, timeout);
return promise.finally(() => {
this.waiting = false;
clearTimeout(timeoutInstance);
});
},
async searchForTerm(term) {
this.results = await this.handleWaiting(this.$wire.query(term), 500);
// do something with the results...
},
}
来源:https://stackoverflow.com/questions/65264570/how-to-avoid-the-explicit-promise-construction-antipattern-for-this-concurrent-t