Javascript 如何从异步函数返回值

Javascript 如何从异步函数返回值,javascript,Javascript,我有一个异步函数,我想从中返回一个值,然后使用它 在updatedStyleSheet函数中,我想返回updated_css,以便在其他地方使用它 async function updatedStyleSheet() { const res = await fetch("./prism.css"); const orig_css = await res.text(); let updated_css = orig_css; const regexp = /(?:var\(--)

我有一个异步函数,我想从中返回一个值,然后使用它

updatedStyleSheet
函数中,我想返回
updated_css
,以便在其他地方使用它

async function updatedStyleSheet() {
  const res = await fetch("./prism.css");
  const orig_css = await res.text();
  let updated_css = orig_css;

  const regexp = /(?:var\(--)[a-zA-z\-]*(?:\))/g;
  let cssVars = orig_css.matchAll(regexp);
  cssVars = Array.from(cssVars).flat();

  for (const v of cssVars) {
     updated_css = updated_css.replace(v,   colors[v.slice(6, -1)]);
   };

// return updated_css ?
}
如果我调用这个函数,我会得到一个Promise对象。这是理所当然的,因为异步函数总是返回一个承诺

我是否可以在
updatedStyleSheet
函数中返回
updated\u css
,然后执行类似操作

const newSheet = updatedStyleSheet().then(css => css)
然后在脚本中的任何位置使用
newSheet
变量

最终目标

获取包含我的css文本内容的
更新的\u css
,并将其用作
href
值,以便用户可以下载样式表

编辑

我试图添加一个事件处理程序,以便在用户保存样式表后,所有选定的颜色值都将保存在样式表中,但它似乎不起作用。我知道这仍然是我对承诺整体理解的一个问题

我做了什么。

const updatedStyleSheet = async () => {
  const res = await fetch("./themes/prism.css");
  const orig_css = await res.text();
  let updated_css = orig_css;

  const regexp = /(?:var\(--)[a-zA-z\-]*(?:\))/g;
  let cssVars = orig_css.matchAll(regexp);
  cssVars = Array.from(cssVars).flat();
  console.log(cssVars)

  for await (const variable of cssVars) {
    const trimmedVar = variable.slice(6, -1)
    const styles = getComputedStyle(document.documentElement)
    const value = String(styles.getPropertyValue(`--${trimmedVar}`)).trim()

    updated_css = updated_css.replace(variable, value);
  }
  console.log(updated_css)

  return updated_css
}

const main = async () => {
  const downloadBtn = document.getElementById('download-btn')
  downloadBtn.addEventListener('click', () => {
    const updated_css = updatedStyleSheet()
    downloadBtn.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(updated_css))
    downloadBtn.setAttribute('download', 'prism-theme.css')
  })
}

main()
我不能
等待
更新的css
,因为它属于click事件的回调,这是一个新函数

然后我做了下面的工作,因为它是顶级的

const downloadBtn = document.getElementById('download-btn')
downloadBtn.addEventListener('click', async () => {
  const updated_css = await updatedStyleSheet()
  downloadBtn.setAttribute('href', 'data:application/octet-stream;charset=utf-8,' + encodeURIComponent(updated_css))
  downloadBtn.setAttribute('download', 'prism-theme.css')
})

这给了我以下错误
TypeError:NetworkError当试图获取资源时。

我将使用.then()函数EX来破坏承诺:

var bar = updatedStyleSheet()
bar.then(updated_css=>{
//logic goes here
});

如果需要等待异步函数返回值(以便以后可以使用此值),请使用
wait
关键字:

const newSheet = await updatedStyleSheet()

但是,请注意,等待会阻止执行,直到函数返回。这可能不是您想要的行为。

是的。由于您已经在使用
async/await
,只需创建一个顶级
async
函数,比如
main
,并在唤醒解决承诺后使用返回的
updated\u css
内容:

async main() {
  const updated_css = await updatedStyleSheet()
  // use css as you please
}

// run program
main()

不要介意多调用一次函数的代价。

是的,
中的
css
,那么
回调将是您返回的项目,但它不会将其返回到外部,您只会得到另一个承诺。您不能从异步代码返回到外部同步代码
新闻单
将再次成为
承诺
。正如@PatrickEvans所说,“您不能从异步代码转到外部同步代码”。但是,正如您所说,您希望将其用作href值,您可以在
.then()
中执行此操作。我已对有关此答案的问题进行了编辑,并添加了一个似乎不起作用的单击事件。