Javascript 从非异步调用Async/await函数,并返回未定义的add value
我不熟悉异步函数。我正在尝试将其应用于UrlFetchApp.fetch。当出现网络问题时,它会抛出一个未定义的错误,因为没有可用的响应代码。因此,我尝试使用异步函数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
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,并且将来会为您带来更多工作。