如何等待异步功能并收集响应

时间:2019-06-24 14:07:23

标签: javascript node.js asynchronous es6-promise

直到现在,我还以为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吗?

4 个答案:

答案 0 :(得分:1)

一个Promise是异步函数的返回。结果可能尚未完成。 这就是为什么您可以等待方法的原因(就像您所做的那样)。计算完成后,这将设置函数的返回值。

或者您可以使用'then':

const data1 = await query.getCachedData(did);
//data1 has a value at this point of code

const data2;
querry.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,您可以让多个方法异步运行并立即等待所有方法。 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

答案 1 :(得分:0)

您是正确的,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 :(得分:0)

await不会使您的异步代码同步-并且应该没有任何合理的理由...在幕后它返回一个promise并与之链接,而不是您必须与之链接然后是你自己。

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

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

如果可行

result.name = await data.name; 

这意味着名称是一个异步获取方法,您必须等待才能获取结果。你也可以这样 data.name.then(name => doWhateverYouWantWithName(name))或像以前一样使用await关键字-甚至更好。

答案 3 :(得分:0)

  

直到现在,我还以为等待使我的程序同步

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

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

  

我看到await仅等待以承诺解决异步功能,然后整个程序继续运行

使用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}`);
  }
})();