将 Async/Await 响应保存在变量上

Posted

技术标签:

【中文标题】将 Async/Await 响应保存在变量上【英文标题】:Save Async/Await response on a variable 【发布时间】:2018-06-27 21:29:19 【问题描述】:

我正在尝试使用 async/await 和 try/catch 来理解异步调用。

在下面的示例中,如何将我的成功响应保存到可在其余代码中使用的变量?

const axios = require('axios');
const users = 'http://localhost:3000/users';

const asyncExample = async () =>
    try 
        const data = await axios(users);
        console.log(data); //200
    
    catch (err) 
        console.log(err);
    
;

//Save response on a variable
const globalData = asyncExample(); 
console.log(globalData) //Promise  <pending> 

【问题讨论】:

globalData 不应该是 undefined,而应该是 Promise(这是异步函数唯一可以返回的内容)。 请注意,async/await 不是“ecmascript-6”(正确的:ECMAScript 2015)。两年后,它们被添加到 ES2017 中。 但是请注意,即使您等待 promise 解析,它的解析值也会是undefined。要使其成为其他内容,您需要在 asyncExample 函数中使用 return @T.J.Crowder 我编辑了这个问题,很抱歉留下旧评论说“未定义”。您将如何将响应保存到可在同一文件范围内的其他地方使用的变量中? 【参考方案1】:

1) 从您的 asyncExample 函数返回一些内容

const asyncExample = async () => 
  const result = await axios(users)

  return result

2) 调用该函数并处理其返回的Promise

;(async () => 
  const users = await asyncExample()
  console.log(users)
)()

这就是为什么你应该这样处理它:

你不能做***await(虽然有a proposal); await 必须存在于 async 函数中。

但是我必须指出,您的原始示例不需要async/await 一点也不;由于axios 已经返回Promise,您可以简单地这样做:

const asyncExample = () => 
  return axios(users)


const users = await asyncExample()

【讨论】:

或者如果你想要async/await 一直向下:pastebin.com/i6FPUs2y(但重要的是,该包装器中的所有代码都在 @987654337 中@/catch -- 如果没有,您会为“未处理的拒绝”错误设置自己。 是的——但不正确。 try/catch(或在结果上使用.catch)不是可选的。 @NicholasKyriakides,太好了!如何使用 try/catch 获得相同的结果? 这不会将返回值保存到变量中。这只是控制台记录返回的值,这不是问题所在。 @danielassayag 它避免了这个问题:***.com/questions/53186265/…【参考方案2】:

try..catch 创建一个新的块作用域。使用lettry..catch 之前定义data 而不是constreturn data 来自asyncExample 函数调用

(async() => 

  const users = 123;

  const asyncExample = async() => 
    let data;
    try 
      data = await Promise.resolve(users);
     catch (err) 
      console.log(err);
    
    return data;
  ;

  //Save response on a variable
  const globalData = await asyncExample();
  console.log(globalData);
  // return globalData;
)();

【讨论】:

@guest271314 这是否意味着我想对全局数据做的任何其他事情都必须在 (async() => )();范围? @tonkihonks13 不,您可以取消注释//return globalData,将.then() 链接到异步箭头函数,并在传递给.then() 的函数处使用传递的参数执行任务 谢谢,我遇到了这个问题。我在设置局部变量时循环了一个数组,当读取该变量时,它仅作为设置的第一个值读取。我用了let,它是固定的。【参考方案3】:

我和你有同样的问题,发现了这篇文章。经过2天的尝试,我终于找到了一个简单的解决方案。 根据the document of JS,async 函数只会返回Promise 对象而不是值。要访问Promise 的响应,您必须使用.then()method 或await 可以返回Promise 的结果对象而不是Promise 本身。 要从 await 更改变量,您可以访问并更改要在异步函数中分配的变量,而不是从它返回。

//Save response on a variable
var globalData;
const asyncExample = async () =>
    try 
        const data = await axios(users);
        globalData = data; // this will change globalData
        console.log(data); //200
    
    catch (err) 
        console.log(err);
    
;
asyncExample();

但是如果你这样做,你可能会得到一个未定义的输出。

asyncExample();
console.log(globalData) //undefined

由于asyncExample()async函数,当console.log被调用时,asyncExample()还没有完成,所以globalData还没有赋值。以下代码将在asyncExample() 完成后调用console.log

const show = async () => 
    await asyncExample();
    console.log(globalData);

show();

【讨论】:

……当然你根本不应该使用globalData,而是让asyncExample 返回值(用它来履行承诺) globalData = data 更改为return dataawait asyncExample(); to let globalData = await asyncExample();`【参考方案4】:

因为事件是异步发生的,所以您需要绑定回调/承诺。我将假设它返回一个承诺。

const axios = require('axios');
const users = 'http://localhost:3000/users';

const asyncExample = async () =>
    try 
        const data = await axios(users);
        console.log(data); //200
    
    catch (err) 
        console.log(err);
    
;

//Save response on a variable
const globalData = asyncExample().then( (success, err) => 
  if (err)  console.error(err); 
  console.log(success)

【讨论】:

“我将假设它返回一个承诺” 没有必要假设。这是一个async 函数。根据定义,它返回一个承诺。但是没有充分的理由用基本的事实错误陈述来回答问题(globalData 仍然是undefined,它不会与问题中的代码一起使用)直到/除非 OP 澄清。 asyncExample 不返回任何内容。您希望console.log(success) 行记录什么?它将记录undefined。 OP 需要 return 来自该函数的 data 另请注意,您的then 回调写得好像它是一个NodeJS 回调(但向后)。真正的then 回调永远不会收到多个参数。【参考方案5】:

只需使用回调/承诺(级联编程):

axios(users).then(function(response) 
    const globalData = response;
    console.log(globalData) 
);

【讨论】:

我在手机上写答案时,上面的答案被提交但我没有看到。我没有复制它。很抱歉造成误解。

以上是关于将 Async/Await 响应保存在变量上的主要内容,如果未能解决你的问题,请参考以下文章

理解ES7中的async/await

async/await 在全局范围内显示数据

在 async/await 上返回多个变量

es6之 async await 使用小计

.save() 无法使用 async/await 正确保存到 mongoDB

在非 UI 线程上运行 async/await 方法[关闭]