javascript - 如何使用 promise 执行函数并通过 API 调用多次检查其值并使用该值执行另一个函数?
问题描述
我正在开发一个应用程序,我需要在一个函数中进行 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 调用是否会运行。有什么想法吗?
解决方案
所以你有几件事在这里发生:
- 您想轮询服务器端进程以完成
- 您想使用服务器端进程成功完成的结果调用另一个函数。
所以让我们写一些助手:
// 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
}
};
推荐阅读
- powershell - Powershell在每个C文件的beinning上设置Header
- apache-spark - 如何缓存火花流数据集
- mysql - 在 MariaDB 中使用过滤器查询 1 到多合一记录
- mysql - 如何并行运行sql查询
- javascript - 引导过滤表多字
- ios - React Native - 如何在 ActionSheetIOS 选项参数中使用 excludeActivityTypes 属性?
- docker-swarm - 在集群环境中访问 cadvisor 的正确方法
- android - 如何将 Gson converterFactory 添加到 Apollo 客户端?
- ios - 如何用布尔值做出“不可定位”的选择?
- rest - 如何在 Kubernetes 中部署的 API 中维护 http 会话?