如何执行带有承诺的函数并通过 API 调用多次检查其值并使用该值执行另一个函数?
Posted
技术标签:
【中文标题】如何执行带有承诺的函数并通过 API 调用多次检查其值并使用该值执行另一个函数?【英文标题】:How can I execute a function with promises and check its value multiple times by API call and execute another function with the value? 【发布时间】:2021-12-20 03:35:38 【问题描述】:我正在开发一个应用程序,我需要在函数中进行 API 调用,然后使用其值进行另一个 API 调用。但是第一个 API 调用的值并不容易获得,因为它取决于一些外部因素。因此,在进行第一次 API 调用后,我需要以 5 秒的间隔进行 3 次 API 调用,以检查该值是否可用。如果是,则进行第二次 API 调用,否则不要进行第二次 API 调用。
现在我知道我必须这样做 Promises 并且我尝试这样做,但我不确定我所做的是否正确。
这就是我可以对 Promise 函数做的事情:
const promiseFunc = ( param1, param2 ) =>
return new Promise(( resolve, reject ) =>
const func1 = api1( param1 );
if ( func1.code === '200' )
const startInterval = setInterval( () =>
const check = getValue();
if ( check && check === param2 )
clearInterval( startInterval );
resolve();
else
reject();
, 5000);
else
reject();
);
所以在上面的 func 中发生的事情是它需要两个参数来调用 api 调用。
func1
被执行,如果它返回 200 则启动间隔计时器。请注意,api1
函数调用是 API 调用。我尝试在那里使用 await 但它会引发错误。而且我不确定我是否可以在 Promise 函数中使用 async/await。
继续,check
变量开始进行 api 调用(getValue()
也是一个包含 api 端点的函数)以检查该值是否可用。如果是则解决,如果不是则拒绝。
这是我按顺序执行 promiseFunc 的方式:
promiseFunc( myChosenValue1, myChosenValue2 )
.then( data =>
return promiseFunc( valueFromFirstExecution1, valueFromFirstExecution2 )
)
.then( () =>
console.log( 'Successfully executed both the functions' );
)
.catch( e =>
console.log( e );
);
这是我在编写 Promise 函数时所能做的最远的事情,我知道上面的代码中存在多个问题。第一个函数得到正确执行,但随后我收到此错误TypeError: Cannot read property 'code' of undefined
。另外,我不确定 setInterval 中的 API 调用是否会运行。有什么想法吗?
【问题讨论】:
【参考方案1】:所以你有几件事在这里发生:
-
您想要轮询服务器端进程以完成
您想使用服务器端进程成功完成的结果调用另一个函数。
所以让我们写一些助手:
// We need a way to wait for some amount of time before
// retrying a request, sleep sleeps for n milliseconds
const sleep = (n) => new Promise(res => setTimeout(res, n));
// We need a unique sentinel value so we know when we have actual
// results from an API call instead of this default value
const sentinel = ; // or Symbol, whatever unique you prefer
// poll will take the data necessary to make a fetch
// request and repeat it every `interval` milliseconds
// up to `maxRetries` until it gets a result
const poll = async (url, fetchOpts, interval, maxRetries) =>
let result = sentinel; // default value
let ticker = 0; // current number of retries
while (result === sentinel && ticker < maxRetries)
// make the api call
const resp = await fetch(url, fetchOpts);
const data = await resp.json();
// do we have a result?
if (isDone(data)) // whatever criteria == completion
result = data; // breaks the loop
else
// wait `interval` milliseconds and try again.
ticker++;
await sleep(interval);
// Oops! We didn't get an answer back from the
// api in time
if (result === sentinel)
throw new Error('Exceeded maxRetries!');
return result;
;
所以现在我们可以真正做我们想做的事了:
// call this with the eventual result, *if* we
// get one
const onSuccess = (result) => ...; // whatever
// This is doing the actual work
const doTheThing = async () =>
await fetch(firstApiCall); // kick off the process
try
// wait for completion
const data = await poll(url, , 5000, 6); // ~30sec timeout
// pass successful result onwards
return onSuccess(data);
catch (err)
// Error bubbling is a little weird with async
// functions, so we'll just handle it here and
// return undefined
console.error(err)
return
;
【讨论】:
对不起,伙计。它在我的头上。如果你能解释一下,那将是一个很大的帮助。 @s.khan 如果我理解你想要的正确,你想要 1. 使用 api 请求在你(或其他人的)服务器上启动一些进程 2. 继续发出另一个 api 请求,直到你取回您使用 (1) 启动的结果 3. 如果您取回它,则将结果传递给另一个函数。准确吗? 是的。如果我从第一个函数中得到结果,则进行与第一个函数相同的 api 调用,但参数不同。 @s.khan 好的。不过,这并没有真正改变答案,只是不用调用某个函数(比如我命名为“onSuccess”的那个),而是用data
再次调用第一个API)。我刚刚添加了一些 cmets,如果还不清楚,请告诉我。
嘿伙计。非常感谢您的时间。但是,我试图理解一个问题。 poll 中的 fetch 函数,和 const check = getValue();
一样吗?还是和const func1 = api1( param1 );
一样?以上是关于如何执行带有承诺的函数并通过 API 调用多次检查其值并使用该值执行另一个函数?的主要内容,如果未能解决你的问题,请参考以下文章