【问题标题】:Why is my code executing although it should pause?为什么我的代码虽然应该暂停但仍在执行?
【发布时间】:2020-09-09 07:42:56
【问题描述】:

我有一个 API,它限制了我每分钟可以向该 API 提供的任何端点发送多少请求(50/分钟)。

在以下代码部分中,我使用 URL 作为属性过滤对象 orders,每个具有提供数据的 URL 的对象都应存储在我的 app.component.ts 中的 successfullResponses 中。

Promise.all(
orders.map(order => this.api.getURL(order.resource_url).catch(() => null))
).then(responses => {
  const successfulResponses = responses.filter(response => response != null)
  for(let data of successfulResponses) {
       // some other requests should be sent with data here
  }
});

要检查的orders 超过50 个,但我一次最多只能检查50 个orders,所以我尝试在我的服务中处理它。我在发送第一个请求时设置了第一个日期。之后,我将新请求的日期与第一个请求的日期进行比较。如果差值超过 60,我将当前日期设置为新日期,并将 maxReq 再次设置为 50。如果小于 60,我检查是否还有请求,如果是,我发送请求,如果没有,我只是等一分钟:

sleep(ms){
    return new Promise(resolve => setTimeout(resolve, ms));
}
async getURL(){
      if(!this.date){
        let date = new Date();
        this.date = date;
      }
      if((new Date().getSeconds() - this.date.getSeconds() > 60 )){
        this.maxReq = 50;
        this.date = new Date();
        return this.http.get(url, this.httpOptions).toPromise();
      } else {
        if(this.maxReq > 0){
          this.maxReq -= 1;
          return this.http.get(url, this.httpOptions).toPromise();
        } else{
          console.log("wait");
         await this.sleep(60*1000);
         this.maxReq = 50;
         this.date = new Date();
         return this.http.get(url, this.httpOptions).toPromise();
        }
      }
  }

但是app.component.ts 中的代码并没有等待函数getURL() 并使用请求执行进一步的代码,这导致了我发送“请求太多太快”的问题。 我该怎么办?

【问题讨论】:

    标签: javascript angular typescript api asynchronous


    【解决方案1】:

    我在尝试使用带有多个异步函数的 Promise 时遇到了类似的问题。这很容易忘记,但为了让它们都等待,您必须在调用相关函数的根行上使用await

    我不完全确定,但我的假设是您的 await this.sleep(60*1000); 行确实在等待超时发生,但是在它这样做的同时,调用 getURL() 的代码正在执行其余的行,因为它在getURL() 之前没有await(或等价物,如.then)。

    我发现这一点的方法是使用一个好的调试工具(我使用了 Chrome DevTools 自己的调试功能)。我建议你也这样做,在各处添加断点,并查看每一行代码的运行情况。

    这是一个简短的粗略示例来说明我的意思:

    // This code increments a number from 1 to 2 to 3 and returns it each time after a delay of 1 second.
    
    async function loop() {
        for (i = 1; i <= 3; i++) {
            console.log('Input start');
            /* The following waits for result of aSync before continuing.
               Without 'await', it would execute the last line
               of this function whilst aSync's own 'await'
               waited for its result.
               --- This is where I think your code goes wrong. --- */
            await aSync(i);
            console.log('Input end');
        }
    }
    
    async function aSync(num) {
        console.log('Return start');
        /* The following waits for the 1-second delay before continuing.
           Without 'await', it would return a pending promise immediately
           each time. */
        let result = await new Promise(
            // I'm not using arrow functions to show what it's doing more clearly.
            function(rs, rj) {
                setTimeout(
                    function() {
                        /* For those who didn't know, the following passes the number
                           into the 'resolved' ('rs') parameter of the promise's executor
                           function. Without doing this, the promise would never be fulfilled. */
                        rs(num);
                    }, 1000
                )
            }
        );
        console.log(result);
        console.log('Return end');
        
    }
    
    loop();

    【讨论】:

      猜你喜欢
      • 2015-11-17
      • 1970-01-01
      • 2012-08-23
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      相关资源
      最近更新 更多