简体   繁体   中英

Is it possible to return a value from a callback inside an async function without using Promise?

Very straightforward question, I know when I write an async function like this:

const res = (async () => 'hello')();
console.log(await res);

It should log: 'hello'

But, lets say I want to timeout the result inside my async function, I would have to create a new Promise so I can wrap the timeout callback in it, like this:

const res = (async () => 
   new Promise(resolve => 
     setTimeout(
       () => resolve('hello'), 1000
     )
   )
)();
console.log(await res);

Well, if async already returns a promise, why should I need to create a new Promise inside a function that is already a promise, to do something as simple as this? Am I missing something or it is indeed designed to be this way? Wouldn't it be better if I could just do something like this in a native way? Is it even possible? For example:

const res = (async () => 
  setTimeout(
    () => resolve('hello'), 1000
  )
)();
console.log(await res);

Ultimately you need to convert a 'callback style' function into a promise, so you can't really get around making that promise. If you think this is a bit ugly, I would suggest using or building a utility function that does this for you.

Aside: unless you use await in a function, there's not really a good reason to mark it as async. This is better:

const res = new Promise(resolve => 
  setTimeout(
    () => resolve('hello'),
    1000
  )
);

console.log(await res);

I think a good way to think about async/await is that it makes certain promise-patterns easier to write, but not everything you can do with a plain promise can also be done with async/await. async/await makes a common pattern (MUCH) more legible.

Generally speaking new Promise is meant for legacy callbacks,. And ideally you want to prevent using them as much as possible.

So in your example your using a setTimeout , and then resolving the string hello . Instead of doing this, it would make more sense to create a delay function, that you could use again then just return "hello"

eg.

 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); async function test() { const res = (async () => { await delay(1000); return "hello"; })(); console.log(await res); } test(); 

Well, if async already returns a promise, why should I need to create a new Promise inside a function that is already a promise, to do something as simple as this?

An async function has three features:

  • It creates a promise
  • The promise resolves with the return value
  • You can use await inside it

This makes it an excellent tool to manage other functions which return promises, as it lets you use await and write code that doesn't use lots and lots of callbacks.

It doesn't make it a universal tool for replacing all other uses of Promise .

You still need one for this.


For example:

 const res = (async () => setTimeout( () => resolve('hello'), 1000 ) )(); console.log(await res); 

If this worked, then the resolve function would be springing out of nowhere, and the return value wouldn't be the value the function resolved as.

It would lose one of the benefits of async functions.


JavaScript is a big toolbox. Different tools are suited to different jobs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM