简体   繁体   English

是否可以在不使用Promise的情况下从异步函数中的回调返回值?

[英]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' 它应该记录:'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: 但是,可以说我想使异步函数中的结果超时,我必须创建一个新的Promise,以便可以将超时回调包装在其中,如下所示:

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? 好吧,如果异步已经返回了一个Promise,为什么我需要在一个已经存在Promise的函数中创建一个新的Promise,来做这样简单的事情? 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. 除了:除非您在函数中使用await ,否则没有充分的理由将其标记为异步。 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. 我认为考虑异步/等待的一个好方法是,它使某些promise-patterns易于编写,但是并非所有可以用普通承诺做的事情也可以通过异步/ await完成。 async/await makes a common pattern (MUCH) more legible. 异步/等待使通用模式(MUCH)更清晰易读。

Generally speaking new Promise is meant for legacy callbacks,. 一般来说, new Promise是用于旧式回调的。 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 . 因此,在您的示例中,您使用setTimeout ,然后解析字符串hello Instead of doing this, it would make more sense to create a delay function, that you could use again then just return "hello" 而不是这样做,创建延迟函数会更有意义,您可以再次使用它,然后只返回"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? 好吧,如果异步已经返回了一个Promise,为什么我需要在一个已经存在Promise的函数中创建一个新的Promise,来做这样简单的事情?

An async function has three features: async功能具有三个功能:

  • It creates a promise 它创造了一个承诺
  • The promise resolves with the return value 承诺以返回值解决
  • You can use await inside it 您可以在其中使用await

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. 这使它成为管理返回承诺的其他功能的出色工具,因为它使您可以使用await并编写不使用大量回调的代码。

It doesn't make it a universal tool for replacing all other uses of Promise . 并不能使其成为替代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. 如果这样做有效,则resolve函数将突然冒出来,并且return将不是该函数解析为的值。

It would lose one of the benefits of async functions. 它将失去async功能的好处之一。


JavaScript is a big toolbox. JavaScript是一个很大的工具箱。 Different tools are suited to different jobs. 不同的工具适合于不同的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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