如何进行一次异步数据库调用并将输出保存供后续函数使用?

huangapple go评论62阅读模式
英文:

How to make one async db call and save output for subsequent functions?

问题

我试图尽量减少数据库查询。目标是进行一次查询,然后在其他函数中使用数据。到目前为止,我有以下代码:

async function GetCoverage(scroll_path) {
  const apiName = "xxxx";
  const path = "/scrolls/" + scroll_path;
  const myInit = {
    headers: {},
    response: false,
  };
  const response = await API.get(apiName, path, myInit);
  console.log("response:", response);
  return response.Items;
}

let dataGlobal;

const getData = async () => {
  const response = await GetCoverage("all");
  dataGlobal = response;
  return response;
};

(async () => {
  await getData();
  console.log("dataGlobal:", dataGlobal);
})();

问题是每次调用await getData() 都会触发另一个数据库查询。我该如何避免这种情况?

英文:

I am trying to keep db queries to a minimum. The goal is to make one query and use data in other functions. So far, I have this code:

async function GetCoverage(scroll_path) {
  const apiName = "xxxx";
  const path = "/scrolls/" + scroll_path;
  const myInit = {
    headers: {},
    response: false,
  };
  const response = await API.get(apiName, path, myInit);
  console.log("response:", response);
  return response.Items;
}

let dataGlobal;

const getData = async () => {
  const response = await GetCoverage("all");
  dataGlobal = response;
  return response;
};

(async () => {
  await getData();
  console.log("dataGlobal:", dataGlobal);
})();

The problem is every await getData() invocation drives another db query. How can I avoid that?

答案1

得分: 2

你基本上想要一个惰性初始化的持久化 Promise 结果。

类似以下代码应该足够了...

let dataGlobal;

const getData = () => (dataGlobal ??= GetCoverage("all"));

第一次调用 getData 时,它将把由 GetCoverage() 返回的 Promise 赋给 dataGlobal 并返回它。

随后的调用将返回已分配的 Promise。


这是一个使用虚拟的 GetCoverage 的快速演示

// 模拟
const GetCoverage = () => {
  console.log("GetCoverage called");
  return new Promise((r) => {
    setTimeout(r, 1000, Math.random());
  });
}

let dataGlobal;

const getData = () => (dataGlobal ??= GetCoverage("all"));

// 进行并行调用
getData().then(console.log.bind(null, "Result #1:"));
getData().then(console.log.bind(null, "Result #2:"));
getData().then(console.log.bind(null, "Result #3:"));

另请参阅Nullish 合并赋值 (??=)

英文:

You basically want a lazily initiated, persistent promise result.

Something like this should suffice...

let dataGlobal;

const getData = () => (dataGlobal ??= GetCoverage("all"));

The first time getData is called, it will assign the promise returned by GetCoverage() to dataGlobal and return it.

Any subsequent calls will return the already assigned promise.


Here's a quick demo using a fake GetCoverage

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// mock
const GetCoverage = () =&gt; {
  console.log(&quot;GetCoverage called&quot;);
  return new Promise((r) =&gt; {
    setTimeout(r, 1000, Math.random());
  });
}

let dataGlobal;

const getData = () =&gt; (dataGlobal ??= GetCoverage(&quot;all&quot;));

// Make parallel calls
getData().then(console.log.bind(null, &quot;Result #1:&quot;));
getData().then(console.log.bind(null, &quot;Result #2:&quot;));
getData().then(console.log.bind(null, &quot;Result #3:&quot;));

<!-- end snippet -->

See also Nullish coalescing assignment (??=)

huangapple
  • 本文由 发表于 2023年5月29日 09:32:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354218.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定