Javascript 从非异步调用Async/await函数,并返回未定义的add value

Javascript 从非异步调用Async/await函数,并返回未定义的add value,javascript,async-await,Javascript,Async Await,我不熟悉异步函数。我正在尝试将其应用于UrlFetchApp.fetch。当出现网络问题时,它会抛出一个未定义的错误,因为没有可用的响应代码。因此,我尝试使用异步函数 var addStamp = obj => { obj.date = new Date(); return obj; } var decideWho = (form) => { var choice = form.choice; var obj = { key1 : 'func1(form.input1

我不熟悉异步函数。我正在尝试将其应用于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;
}
当通过decideWho调用func1时,它返回结果并执行addStamp,以便将日期添加到返回值中

但当调用func2时,它会正确返回值,但从decideWho开始,addStamp在返回之前不会执行,因此“date”未定义。在这次事件中,我必须在返回值的同时调用func2中的addStamp

如何避免这种未定义的情况?

我肯定我搞砸了async/await

我试图将async/await放在decideWho中,方法是用await声明额外的值,然后用addStamp包装它,然后返回它

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

但是,当使用google.script.run从客户端调用decideWho时,它会抛出未定义的错误。我想我需要添加一个地方,等待更多的时间,但我不知道在哪里

值得一提的几点 (*因为来自客户端的表单调用各种函数,所以我决定将bunch放在一个bucket中。也就是说,不管选项是什么,它都只从客户端调用服务器函数的decideWho,并且通过选项的值,它将选择使用参数调用哪个函数。每个函数都从decideWho so t返回值和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()})

多亏了乔希和安迪

我认为这应该对你有用。它还有其他几个重构功能

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

// 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: ""};
  }
}

我想这应该对你有用。它还有其他几个重构功能

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

// 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: ""};
  }
}

嘿,所以我写了一些与你非常相似的东西(在一个对象中等待函数并映射它们),但你抢先了我一步。我想我也可以发布我的工作/想法:老兄,你当时全力以赴!干得好。箭头函数单行或返回对象(如代码笔的第10行)不需要
{
。要返回对象,可以执行以下操作:
()=>({a:3})
啊,当然,我只是倾向于在试图教别人时使用显式返回-我认为它们更清晰一些。相关讨论:谢谢你们两位。除了我原来的问题之外,我学到了很多要点。但是,出于某种原因,我不能放弃求值。如果我在调用funcMap[choice]时保留没有引号的函数,它会迭代所有函数。通过决定什么是异步不起作用的。正如Josh在第一行中提到的,主要问题是在obj中添加了一个项。我在这里添加了async/await瞧!但我想知道的是,为什么第一个func1总是起作用,而func2从一开始就不起作用。然后一个想法出现了,可能是JSON.parse使它同步了,但是func2没有。谢谢你的帮助!!!如果你想弄清评估的真相,制作一个最小的复制器,并提出另一个问题。如果我在写代码,我会非常担心,我不明白发生了什么。如果你知道你不知道你的代码是如何运行的,那么你不知道你在做什么“不知道”可能会导致其他难以追踪的bug,并且将来会有更多的工作要做。嘿,所以我写了一些与您非常相似的东西(等待对象中的函数并映射它们)但是你抢先了我。我想我也可以发布我的工作/想法:伙计,你全力以赴!干得好。箭头函数单行或返回对象(如代码笔的第10行)不需要
{
。要返回对象,你可以做:
()=>({a:3})
啊,当然,我只是倾向于在试图教别人时使用显式返回-我认为它们更清晰一些。相关讨论:谢谢你们两位。除了我原来的问题之外,我学到了很多要点。但是,出于某种原因,我不能放弃求值。如果我在调用funcMap[choice]时保留没有引号的函数,它会迭代所有函数。通过决定什么是异步不起作用的。正如Josh在第一行中提到的,主要问题是在obj中添加了一个项。我在这里添加了async/await瞧!但我想知道的是,为什么第一个func1总是起作用,而func2从一开始就不起作用。然后一个想法出现了,可能是JSON.parse使它同步了,但是func2没有。谢谢你的帮助!!!如果你想弄清评估的真相,制作一个最小的复制器,并提出另一个问题。如果我在写代码,我会非常担心,我不明白发生了什么。如果你知道你不知道你的代码是如何运行的,那么你不知道你在做什么“不知道”可能会导致其他难以追踪的bug,并且将来会为您带来更多工作。