gpt4 book ai didi

javascript - 避免在 then 函数 JS 中嵌套 Promise

转载 作者:太空宇宙 更新时间:2023-11-04 02:55:38 24 4
gpt4 key购买 nike

我有一个异步函数“doApiRequest”,在“then”函数内部调用...

doSomething()
.then(() => {
return doApiRequest();
})
.then((apiResult) => {
doSomethingElse(apiResult);
});

问题在于 doApiRequest 返回一个包含该 API 请求的最终结果的 Promise。然而,根据我正在使用的 API 的性质,涉及到请求速率限制。我计划通过让每个 API 请求将自身添加到队列中来处理这个问题,然后当队列在等待速率限制后释放请求时,API 请求将完成解析。虽然我可以做类似的事情...

doSomething()
.then(() => {
return waitForRateRefresh();
})
.then(() => {
return doApiRequest();
})
.then((apiResult) => {
doSomethingElse(apiResult);
});

我可能最终会进行许多“doApiRequest”调用,因此必须在每个调用上链接“waitForRateRefresh”似乎是一个糟糕的方法,我还必须使其工作,以便它可以传递之前的 then 语句中的数据。我想做的是在“doApiRequest”本身内部处理这个问题。

“doApiRequest”看起来像这样

doApiRequest(){
return new Promise((resolve, reject) => {
waitForRateRefresh().then(() => {
//http call
resolve(someValue);
};
});
}

但是我正在尝试找到一种不涉及嵌套 Promise 的方法来做到这一点。还有什么其他方法可以解决这个问题。我想到的另一种方法是使用 Async/Await 来代替,有没有其他方法可以只用 promise 来做到这一点?从“doApiRequest”返回带有附加 then 函数的 Promise 会发生什么(或者甚至可能),例如...

return waitForRateRefresh().then(() => new Promise(..../http call));

在调用“doApiRequest”的原始 then 函数中 - 它将接收“waitForRateRefresh”返回的值,还是沿着附加的 then 链遍历的结果。

感谢您的见解

最佳答案

虽然 async/await 很棒,但如果您使用的是不支持它的旧版本的 Nodejs,那么您要么需要转译 async/await 代码,要么使用普通的 Promises

不知道你是否见过转译的 async/await - 它相当“冗长”

假设您实际上想要将 doSomething 的结果传递给 doApiRequest ,您可以做什么

doSomething()
.then(result => waitForRateRefresh().then(() => result))
.then((doSomethingResult) => doApiRequest(doSomethingResult))
.then((apiResult) => doSomethingElse(apiResult));

当然,上面可以简化为

doSomething()
.then(result => waitForRateRefresh().then(() => result))
.then(doApiRequest)
.then(doSomethingElse);
<小时/>

澄清有关 Promise 构造函数反模式的一点

doApiRequest(){
return new Promise((resolve, reject) => {
waitForRateRefresh().then(() => {
//http call
resolve(someValue);
};
});
}

这被简化为

doApiRequest(){
return waitForRateRefresh().then(() => {
//http call
return someValue;
};
}

当然,如果//http call是异步的,那么return someValue就不能这样使用。但您的代码版本也会出现这种情况

要在此版本的 doApiRequest 中接受来自 doSomething 的值,请将代码更改为

doApiRequest(someResult){
return waitForRateRefresh().then(() => {
//http call - use someResult here
return someValue;
};
}

现在主要代码

doSomething()
.then(doApiRequest)
.then(doSomethingElse);

不过,如果someValue在任何http调用中异步收集,//http调用返回someValue将无法按预期工作

<小时/>

还有一个想法,这样您就无需重写现有函数

围绕doApiRequest创建一个“包装器”

const qApiRequest = result => waitForRateRefresh().then(() => doApiRequest(result));

现在,代码是

doSomething()
.then(qApiRequest)
.then(doSomethingElse);
<小时/>

当然,使用async/await就可以了

const doSomethingResult = await doSomething();
await waitForRateRefresh();
const apiResult = doApiRequest(doSomethingResult);
const finalResult = doSomethingElse(apiResult);

当然,这些需要位于标记为async的函数内

关于javascript - 避免在 then 函数 JS 中嵌套 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49744219/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com