【问题标题】:Async/Await returning result not promise异步/等待返回结果不承诺
【发布时间】:2019-10-20 02:51:00
【问题描述】:

我对异步/等待很困惑。我一直在阅读关于 s/o 的答案,但我不明白 async/await 是否真的做了我想要的。

我正在尝试以同步方式返回异步调用的结果,也许这就是我失败的原因,也许不是为此而设计的?我不想返回回调(或承诺),而是返回一个结果。

这就是我一直在尝试做的事情

 let namespace = {};

 namespace.Test = class{

      constructor(){

      }        


      async get(){
           let response = await this._load();       
           let data = await response;
           console.log(data); //Logs my data but return Promise instead
           return data;  
      }

     _load(){
         let promise = new Promise((resolve, reject) => {       
             fetch('https://jsonplaceholder.typicode.com/todos/1')
            .then(function(response){
                resolve(response.json());                
            }).catch(error =>  reject(error));           
         });
         return promise;
     }

  }


  //The goal is to figure out if I can have that
  let myTest = new namespace.Test();
  //Here I want data NOT a promise
  let res = myTest.get();

  console.log(res); //logs a Promise but I want what has been resolved instead

我认为解决 _load 中的承诺,然后在 get 中使用 await 可以做到这一点?

【问题讨论】:

  • async 函数会立即返回一个 Promise,当它们到达 return 时,该 Promise 就会被解析。没有回头路了,对不起。 :)
  • 不应该this._load()指向空的构造函数中的load()或者在构造函数之前作为私有?
  • @zer00ne 不,我不希望类在开始时加载
  • @Eric 你只有一个线程,这是一个有很多好处的设计选择,但也有一些缺点。缺点之一是您需要决定如何处理异步事物。 JS 选择了不阻塞线程,这在 99% 的情况下几乎可以肯定是正确的选择。有时它会让事情变得不那么方便,但是一旦你习惯了它就不会那么难了。
  • 您尝试过新的 getter 语法吗? get async retrieve() {... 不是 100% 关于 async 部分

标签: javascript async-await


【解决方案1】:

我正在尝试以同步方式返回异步调用的结果

那是不可能的。异步函数同步返回的唯一内容是一个 Promise(所有异步函数都返回 Promise,按照设计)。异步函数使使用 Promise 的语法更容易,但它们仍然是异步的。

当您在异步函数中使用await 时,这将延迟返回的承诺解决所需的时间。这很好:如果任何代码正在等待该承诺,它将等待更长的时间,因此将推迟到您的异步功能完全完成。但是等待承诺不是自动的;你要么需要使用 promise 的 .then 方法,要么需要在 async 函数中使用 await 关键字。

let resPromise = myTest.get();
resPromise.then(res => console.log(res));
async someFunction() {
  const res = await myTest.get();
  console.log(res);
}

【讨论】:

  • 那么 async/await 就完全傻了?为什么在您返回之前将某些东西命名为“等待”,它在语义上表示等待并让它做其他事情?我错过了重点吗?
  • 它的目的是使使用 Promise 的语法更容易。当您在异步函数中时,语法看起来更像线性同步代码(与 .then 回调相比),这更容易理解。但它仍然是异步的,并且仍然使用 Promise。通常,使用 Promise 的代码具有传染性:如果一个函数使用 Promise,那么任何依赖于它的函数也需要使用 Promise。
  • @Eric 是的,您缺少的一点是async-await 的目的是使异步函数的语法inside 更具可读性。它使处理异步进程成为可能,而无需嵌套和链接then() 回调。异步函数之外的一切都完全不知道函数内部发生的事情。没关系,它仍然是一个异步函数,所以无论如何它都会返回一个承诺。这绝对不傻。
  • “更具可读性”是我听到的,所以这只是编码人员的语义?这很愚蠢,因为我可以读回我自己的代码......无论如何,谢谢。
  • 是的,你没听错。目的是使其更具可读性(和可写性)。无论有没有异步函数,javascript 仍然是单线程的,并使用回调作为异步工作完成后恢复的机制。 Promise 是回调之上的抽象,async/await 是 Promise 之上的抽象。如果您发现 async/await 没有用,那很好:您可以在 raw 中使用 promises 或在 raw 中使用回调。但这些是你做异步事情的选择。同步返回异步值不是 javascript 中的选项。
【解决方案2】:

由于fetch() 已经返回了一个promise,没有理由将它包装在另一个promise 中。

 _load(){ return fetch('https://jsonplaceholder.typicode.com/todos/1')}

【讨论】:

  • 我不想回报承诺!!!承诺解决后,我正在尝试返回...
  • @Eric 你的问题不是关于如何返回承诺吗?
  • @OlegI,不是在使用 async/await 解决承诺时返回
  • 异步是关于管理承诺伙伴的。如果您不返回Promise(),则await 将一无所获。
  • @Lennholm 当我专门使用“等待”返回时,这不是时间旅行。我等着呢!
【解决方案3】:

我们可以通过在全局自调用函数中指定异步来尝试这个,

(async function() {
let namespace2 = {};

 namespace2.Test = class{

      constructor(){

      }        


      async get(){
           let response = await this._load();       
           let data = await response;
           console.log(data); //Logs my data but return Promise instead
           return data;  
      }

     _load(){
         let promise = new Promise((resolve, reject) => {       
             fetch('https://jsonplaceholder.typicode.com/todos/1')
            .then(function(response){
                resolve(response.json());                
            }).catch(error =>  reject(error));           
         });
         return promise;
     }

  }



  //The goal is to figure out if I can have that
  let myTest2 = new namespace2.Test();
  //Here I want data NOT a promise
  let res2 = await myTest2.get();

  console.log(res2);
})();

【讨论】:

    【解决方案4】:

    您可以通过await 执行此操作(请参阅https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/await

    所以你只需写:

    //Here I want data NOT a promise
    let res = await myTest.get();
    

    console.log(res); 现在将返回解析后的值。

    【讨论】:

    • 但它没有? await 仅在异步函数和异步生成器中有效
    • @Eric 没错,在同步 JS 中等待某些东西是不可能的,因为这意味着阻塞 JS 运行的整个单线程,这不是一个选项。
    猜你喜欢
    • 1970-01-01
    • 2019-03-20
    • 2017-02-03
    • 2019-07-20
    • 2022-01-09
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    相关资源
    最近更新 更多