【问题标题】:Call Async/await function from non async and add value returns undefined从非异步调用 Async/await 函数并添加值返回未定义
【发布时间】:2020-06-06 18:16:15
【问题描述】:

我是异步函数的新手。我正在尝试将它应用于 UrlFetchApp.fetch。当出现网络问题时,它会抛出未定义的错误,因为没有可用的响应代码。因此,我尝试了异步功能。

var addStamp = obj => {
  obj.date = new Date();
  return obj;
}
var decideWho = (form) => {
  var choice = form.choice;
  var obj = { key1 : 'func1(form.input1)',
key2 : 'func2(form.input2)'......};
return addStamp(eval(obj[choice]||obj[default]));
}

const fetchUrl = async (url, params) => {
  let data = await UrlFetchApp.fetch(url,params).getContentText();
  return JSON.parse(data);
}

var func1 = async (val) => {
  var params = {...};
  let response = await fetchUrl(val, params);
  return response["message"];
}

var func2 = async (val) => {
  var params = {...};
  let response = await UrlFetch.app(val, params);
  if (response.getResponseCode() === 200) {
       var result = {step:"file", result:response};
    } else var result = {step: null, result: ""};
  return result;
}

当通过decisionWho 调用func1 时,它返回结果并执行addStamp,以便将日期添加到返回值中。

但是当 func2 被调用时,它会正确返回值,但是从 decisionWho 中,addStamp 在它返回之前没有执行,所以 'date' 是未定义的。在这个事件中,我必须在 func2 中调用 addStamp,同时返回值。

如何避免这种未定义?

我确定我搞砸了异步/等待。

我试图通过用 await 声明额外的值然后用 addStamp 包装它然后返回它来将 async/await 放入decisionWho。

let result = await eval(obj[choice]||obj[default]);
return addStamp(result);
}

但是,当使用 google.script.run 从客户端调用 decisionWho 时,它会引发未定义的错误。我想在某个地方我需要再添加一次等待,但我不知道在哪里。

值得一提的几点 (*由于客户端的表单调用了各种函数,所以我决定将一堆放在一个桶中。即不管选项如何,它只会从客户端调用服务器函数的decisionWho,并通过选项的值来选择哪个函数将用参数调用。每个函数都从decisionWho返回值和addStamp,这样我就不必在每个函数中重复这个过程/代码。 **只有 func1 和 func2 是异步的,其他的不是。)

成功了

const addStamp = async (obj) => {
  const temp = await obj;
  temp.date = new Date();
  return temp;
}

或更短的版本

const addStamp = async (obj) => (
  { ...(await obj),
  date: new Date()})

感谢乔希和安迪

【问题讨论】:

    标签: javascript async-await


    【解决方案1】:

    我认为这应该适合你。它还有其他几个重构...

    在我看来,基本问题是当您将异步函数添加到对象时,您并没有等待它们。

    // use const - variables are unreliable!
    // Rest Spread syntax
    const addStamp = obj => ({
      ...obj,
      date: new Date();
    })
    
    // this can throw on a network or JSON parse error,
    // the fn that calls (and awaits / .then chains)
    // on decideWho needs to handle that.
    const decideWho = async form => {
      const { choice } = form;
      // you need to await these, they are async
      const obj = { 
         key1 : await func1(form.input1),
         key2 : await func2(form.input2)
      };
      return addStamp(eval(obj[choice]||obj[default]));
    }
    
    // can throw from network or JSON parse
    const fetchUrl = async (url, params) => {
      let data = await UrlFetchApp.fetch(url,params).getContentText();
      return JSON.parse(data);
    }
    
    const func1 = async val => {
      const params = {...};
      let response = await fetchUrl(val, params);
      return response["message"];
    }
    
    const func2 = async val => {
      const params = {...};
      const response = await UrlFetch.app(val, params);
      // use a ternary, and no intermediate var
      return (response.getResponseCode() === 200) ?
         {step:"file", result:response} :
         {step: null, result: ""};
      }
    }
    

    【讨论】:

    • 嘿,所以我正在写一些与你超级相似的东西(等待对象中的函数并映射它们),但你打败了我。想我也可以发布我的工作/想法:codepen.io/AndyMardell/pen/BaNQVzB?editors=0012
    • 老兄,你全押!不错的作品。箭头函数单行或返回一个对象(如代码笔的第 10 行)不需要{。要返回一个对象,你可以这样做:() => ({a: 3})
    • 啊,当然,我只是在尝试教别人时倾向于使用明确的回报——我认为他们更清楚一点。相关讨论:twitter.com/markdalgleish/status/1225205953093459968
    • 谢谢你们俩。除了我原来的问题,我学到了很多点。但是,由于某种原因,我不能放弃 eval。如果我保留不带引号的函数,当我调用 funcMap[choice] 时,它会迭代所有函数。并且通过使 decisionWho 异步不起作用。正如 Josh 在第一行中提到的,主要问题是向 obj 添加一个项目。在那里我添加了异步/等待瞧!但我想知道的一件事是,为什么第一个 func1 总是有效,而 func2 从一开始就没有工作。然后一个想法来了,也许 JSON.parse 使它同步但 func2 没有。谢谢你帮助我!!!
    • 如果您想深入了解该 eval 的事情,请制作一个最小的复制器并打开另一个问题。如果我正在编写代码,我会非常担心,我不明白发生了什么。如果这就是你知道你不知道你的代码是如何运行的,那么你不知道你不知道的可能会导致其他难以追踪的错误,并且将来会为你做更多的工作。跨度>
    猜你喜欢
    • 1970-01-01
    • 2021-03-15
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2018-09-30
    • 2021-08-06
    • 2019-03-01
    相关资源
    最近更新 更多