Let's say I have an API that expects a promise as an argument:
async function doSomething(somePromise) {
somePromise.then(someOutcome => console.log(someOutcome))
}
And let's say I have some trivial logic for something I want to pass into that API: return 'hi'
I believe these two approaches to calling the API are functionally equivalent - but is one more idiomatic/clear than the other?
/* A */ doSomething(Promise.resolve('hi'))
/* B */ doSomething((async () => 'hi')())
Now, imagine I have another API that expects a function as argument, which is expected to return a promise:
async function doSomethingElse(someFunction) {
someFunction().then(someOutcome => console.log(someOutcome))
}
In this case, which is most idiomatic?
/* C */ doSomethingElse(() => Promise.resolve('hi'))
/* D */ doSomethingElse(async () => 'hi')
I suspect the correct answers are "A" and "D", but it feels surprising that a developer would be expected to sometimes think in terms of explicit Promises, and sometimes think in terms of async.
I had read somewhere something along the lines of "If you're typing Promise, you're probably doing something wrong". Is that a gross oversimplification?
And final question: If the API steps away from explicit promises and uses await directly (effectively supporting a promise or a value) - is that really the answer? That the API itself in my first example was the "problem" for modern idiomatic JS?
async function doSomethingThird(someValueOrPromise) {
simpleValue = await someValueOrPromise
console.log(simpleValue)
}
/* E */ doSomethingThird(Promise.resolve('hi'))
/* F */ doSomethingThird((async () => 'hi')())
/* G */ doSomethingThird('hi')