【问题标题】:How to await on async function and collect the response如何等待异步功能并收集响应
【发布时间】:2019-11-06 08:48:05
【问题描述】:

直到现在,我认为await 使我的程序同步。但是,我看到await 只等待async 函数通过承诺解决,然后整个程序继续运行。那么,等待和收集异步函数响应的正确方法是什么?

原码:

let result={
  name:'',
  country:''
};
const data = await query.getCachedData(did); 
result.name = data.name; // undefined
result.country = data.country;//undefined
console.log(result);

我不知道为什么,但等待异步函数结果有效:

let result={
  name:'',
  country:''
};
const data = await query.getCachedData(did); 
result.name = await data.name; //'Jon'
result.country = await data.country;// 'US'
console.log(result);

但我不确定这是否是解决方案。

由于getCachedData 返回了承诺,我认为这可能是正确的方法,但then()/catch() 没有执行。

query.getCachedData(did).then((tfnData) => {
  result.name = data.name; 
  result.country = data.country;
  console.log(result);
}).catch((dbError) => {
  console.log(dbError);
});

谁能纠正我以正确的方式获取result

【问题讨论】:

  • 我将重申罗伯特的评论,因为我认为他没有足够的代表来发表实际评论。请提供getCachedData 的来源或提供足够的信息来重现此问题。您使用的是什么数据库库?我们怎么能导致这种情况发生在我们身上?请阅读minimal reproducible example
  • query.getCachedData 是异步方法吗?你能告诉我们这个方法是什么样的吗?我怀疑这是一个异步方法或者它返回一个承诺,因为你不能等待它并且你不能执行 then/catch

标签: javascript node.js asynchronous es6-promise


【解决方案1】:

await 等待 async 函数返回一个承诺是正确的。对于您的代码示例,我建议如下:

let result={
    name:'',
    country:''
};

async function getData() {
    const data = await query.getCachedData(did);
    result.name = data.name; // 'Jon'
    result.country = data.country; // 'US'
    console.log(result);
}

await 只能在 async 函数内使用。它将暂停函数,直到收到来自query.getCachedData() 的承诺,将该响应保存到const data,然后可用于设置result 对象的名称和国家/地区。您还可以查看 asyncawait 的 MDN 文档。

【讨论】:

    【解决方案2】:

    await 不会使您的异步代码同步 - 并且不应该有任何合理的理由这样做......在幕后它返回一个承诺并将其与 then 链接,而不是您必须自己与 then 链接.

    您使用 then 关键字所做的,就是 await 为您所做的。

    您可以使用任何适合您的方式,但async/await 使您的代码更易于阅读。

    如果可行

    result.name = await data.name; 
    

    这意味着 name 是一个异步 getter 函数,您必须 await 让它得到结果。你也可以这样做 data.name.then(name => doWhateverYouWantWithName(name)) 或像您已经使用的那样使用 await 关键字 - 这应该会更好。

    【讨论】:

      【解决方案3】:

      Promise 是异步函数的返回值。结果可能还没有完成。 这就是为什么你可以等待一个方法(就像你做的那样)。这将在计算完成时设置函数的返回值。

      或者你可以使用'then':

      const data1 = await query.getCachedData(did);
      //data1 has a value at this point of code
      
      const data2;
      query.getChachedData(did).then((result)=>{data2 = result});
      //data2 can have a value or will get one later (this is async) at this point of code
      

      使用 Promise all,您可以让多个方法异步运行并同时等待。 https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

      const callStack = [];
      
      const data1;
      const data2;
      callStack.push(query.getChachedData(did).then((result)=>{data1 = result}));
      callStack.push(query.getChachedData(did).then((result)=>{data2 = result}));
      //run both query Methods at asynchronous 
      await Promise.all(callStack);
      //data1 and data2 hava a value at this point of code
      

      【讨论】:

        【解决方案4】:

        到目前为止,我认为 await 使我的程序同步

        Async/await 使代码看起来像同步的,但后面只是 语法糖 用于 Javascript 中的承诺。 真的吗? Yes

        只是return thePromise().then(result => result)

        我看到 await 只等待异步函数通过 promise 解决,然后整个程序继续运行

        当您使用 Promise 时,它​​们不会使 Node.js 代码同步运行,另一方面,Promise 允许您编写看起来是同步的流。

        那么,等待和收集来自异步函数的响应的正确方法是什么?

        根据您的示例,代码将是这样的:

        const queryResult = did => query.getCachedData(did).then(tfnData => tfnData);
        
        // Without async/await    
        queryResult(did)
          .then(data => {
            const { name, country } = data;
            const result = { name, country };
            console.log(`${result.name}, ${result.country}`); // Jon, US
          })
          .catch(error => console.log(`Error produced: ${error}`));
        
        // With async/await
        (async () => {
          try {
            // ... Some other code ....
            // ... Some other code ....
            // ... Some other code ....
        
            const data = await queryResult(did);
            const { name, country } = data;
            const result = { name, country };
            console.log(`${result.name}, ${result.country}`); // Jon, US
          } catch (error) {
            console.log(`Error inside try-catch: ${error}`);
          }
        })();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-03
          • 2013-08-29
          • 1970-01-01
          • 2023-04-08
          • 1970-01-01
          • 2020-02-26
          相关资源
          最近更新 更多