Javascript 避免then函数JS中的嵌套承诺
我有一个异步函数“doApiRequest”,它在“then”函数中调用Javascript 避免then函数JS中的嵌套承诺,javascript,node.js,promise,async-await,Javascript,Node.js,Promise,Async Await,我有一个异步函数“doApiRequest”,它在“then”函数中调用 doSomething() .then(() => { return doApiRequest(); }) .then((apiResult) => { doSomethingElse(apiResult); }); 问题是doApiRequest返回一个带有该API请求最终结果的承诺。然而,我正在使用的API的性质有一个请求速率限制。我计划通过让每个API请求将其自身添加到队
doSomething()
.then(() => {
return doApiRequest();
})
.then((apiResult) => {
doSomethingElse(apiResult);
});
问题是doApiRequest返回一个带有该API请求最终结果的承诺。然而,我正在使用的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);
};
});
}
然而,我正试图找到一种不涉及嵌套承诺的方法来实现这一点。还有什么其他方法可以解决这个问题。我想到的另一种方法是使用Async/Await,有没有其他方法只使用承诺?从'doApiRequest'返回带有附加then函数的承诺会发生什么(或者甚至可能发生什么),如
return waitForRateRefresh().then(() => new Promise(..../http call));
在调用“doApiRequest”的原始then函数中,它将接收“waitForRateRefresh”返回的值,还是沿着连接到它的then链向下遍历的结果
感谢您提供的任何见解我将使用
async/await
,它可以使代码非常可读,并且可以很容易地推断接下来会发生什么
await doSomething();
await waitForRateRefresh();
const apiResult = await doApiRequest();
await doSomethingElse(apiResult);
我会使用
async/await
,它可以使代码非常可读,并且可以很容易地推断接下来会发生什么
await doSomething();
await waitForRateRefresh();
const apiResult = await doApiRequest();
await doSomethingElse(apiResult);
虽然async/await很棒,但如果您使用的是不支持它的旧版本的nodejs,那么您要么需要传输
async/await
code,要么使用普通的ol承诺
不知道您是否见过transpiledasync
/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);
doApiRequest(){
return waitForRateRefresh().then(() => {
//http call
return someValue;
};
}
澄清关于promise构造函数反模式的一点
doApiRequest(){
return new Promise((resolve, reject) => {
waitForRateRefresh().then(() => {
//http call
resolve(someValue);
};
});
}
这被简化为
doSomething()
.then(result => waitForRateRefresh().then(() => result))
.then(doApiRequest)
.then(doSomethingElse);
doApiRequest(){
return waitForRateRefresh().then(() => {
//http call
return someValue;
};
}
当然,如果//http调用
是异步的,那么返回someValue
就不能这样使用。但是你的代码版本也是如此
要在此版本的doApiRequest中接受doSomething中的值,请将代码更改为
doApiRequest(someResult){
return waitForRateRefresh().then(() => {
//http call - use someResult here
return someValue;
};
}
主代码现在是
doSomething()
.then(doApiRequest)
.then(doSomethingElse);
再说一遍,尽管。。。如果在任何http调用
中异步收集someValue
,则//http调用
和返回someValue
将无法正常工作
还有一个想法,这样您就不需要重写现有函数了 围绕
doApiRequest
const qApiRequest = result => waitForRateRefresh().then(() => doApiRequest(result));
现在,代码是
doSomething()
.then(qApiRequest)
.then(doSomethingElse);
当然,使用
async
/wait
只需
const doSomethingResult = await doSomething();
await waitForRateRefresh();
const apiResult = doApiRequest(doSomethingResult);
const finalResult = doSomethingElse(apiResult);
当然,当async/await很棒时,这些需要在标记为
async
的函数中,如果您使用的是不支持它的旧版本的nodejs,那么您要么需要传输async/await
代码,要么使用普通的ol承诺
不知道您是否见过transpiledasync
/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);
doApiRequest(){
return waitForRateRefresh().then(() => {
//http call
return someValue;
};
}
澄清关于promise构造函数反模式的一点
doApiRequest(){
return new Promise((resolve, reject) => {
waitForRateRefresh().then(() => {
//http call
resolve(someValue);
};
});
}
这被简化为
doSomething()
.then(result => waitForRateRefresh().then(() => result))
.then(doApiRequest)
.then(doSomethingElse);
doApiRequest(){
return waitForRateRefresh().then(() => {
//http call
return someValue;
};
}
当然,如果//http调用
是异步的,那么返回someValue
就不能这样使用。但是你的代码版本也是如此
要在此版本的doApiRequest中接受doSomething中的值,请将代码更改为
doApiRequest(someResult){
return waitForRateRefresh().then(() => {
//http call - use someResult here
return someValue;
};
}
主代码现在是
doSomething()
.then(doApiRequest)
.then(doSomethingElse);
再说一遍,尽管。。。如果在任何http调用
中异步收集someValue
,则//http调用
和返回someValue
将无法正常工作
还有一个想法,这样您就不需要重写现有函数了 围绕
doApiRequest
const qApiRequest = result => waitForRateRefresh().then(() => doApiRequest(result));
现在,代码是
doSomething()
.then(qApiRequest)
.then(doSomethingElse);
当然,使用
async
/wait
只需
const doSomethingResult = await doSomething();
await waitForRateRefresh();
const apiResult = doApiRequest(doSomethingResult);
const finalResult = doSomethingElse(apiResult);
当然,这些将需要在标记为
async
的函数中注意:'doApiRequest'看起来像这样的
避免承诺构造函数反模式。。。该函数的内容只是return waitForRateRefresh()。然后(()=>{//http call return someValue;};
就像您一样。然后(()=>{return waitForRateRefresh();})
和doApiRequest
一样,没有传入的“值” anyway@JaromandaX当然,在这种情况下,虽然“someValue”会变成原始的then语句,或者只会变成waitForRateRefresh解析为返回的语句,但这是非常有帮助的,尤其是能够包装它。我在这里创建了一个JSBin来测试一些不同的方法和返回值注意:“doApiRequest”看起来会有些问题像这样
避免promise构造函数反模式…该函数的内容只是return waitForRateRefresh()。然后(()=>{//http call return someValue;};
看到你的。然后(()=>{return waitForRateRefresh();})
对于doApiRequest
也是如此……没有传入的“值”anyway@JaromandaX当然,在这种情况下,虽然“someValue”会变成原来的then语句,或者只返回waitForRateRefresh解析为返回的内容,但这是非常有帮助的,尤其是能够包装它