Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 避免then函数JS中的嵌套承诺_Javascript_Node.js_Promise_Async Await - Fatal编程技术网

Javascript 避免then函数JS中的嵌套承诺

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请求将其自身添加到队

我有一个异步函数“doApiRequest”,它在“then”函数中调用

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承诺

不知道您是否见过transpiled
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);
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承诺

不知道您是否见过transpiled
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);
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解析为返回的内容,但这是非常有帮助的,尤其是能够包装它