【问题标题】:Execute a sequential requests handling each one执行处理每个请求的顺序请求
【发布时间】:2019-06-24 23:04:21
【问题描述】:

我需要按顺序发送请求,但在返回错误时停止顺序,我正在使用来自 Angular 的 $http 提供程序。

我的代码是这样的:

const steps = [
    { url: '/api/test/1' },
    { url: '/api/test/2' },
    { url: '/api/test/3' },
    { url: '/api/test/4' },
]

const executeStep = index => {
    // Validate step existence
    if (typeof steps[index] == 'undefined') return
    // Request
    $http({method: 'get', url: steps[index].url})
    .success(response => {
        if (!response.success) throw response
        executeStep(index+1)
    }).error(err => {
        console.error(err)
        alert('Error')
    })
}

executeStep(0)

我的问题是:有更好的方法来完成这项工作吗?

【问题讨论】:

    标签: javascript arrays angularjs recursion


    【解决方案1】:

    这里是代码,和你的很相似,但是没有处理或添加索引号,所以更清楚一点。

    const queue = [
      { url: '/api/test/1' },
      { url: '/api/test/2' },
      { url: '/api/test/3' },
      { url: '/api/test/4' },
    ];
    
    function runQueue() {
      const req = queue[0];
    
      $http({method: 'get', url: req.url})
      .success(response => {
        console.log(response);
        queue.shift();
        if (queue.length > 0) {
         runQueue();
        }
      })
      .error(err => {
        console.error(err);
      })
    }
    

    使用 Bluebird Promises 的解决方案。

    另一个不错的选择是使用bluebird Promise 库(尤其是如果您的代码是服务器端nodejs)。 这个库现在不是很流行,因为几乎所有地方都原生支持 Promises。但仍有一些方法非常有用。在您的情况下,Promise.each method 将完美运行。

    const Promise = require('bluebird'); // or import * as Promise from 'bluebird';
    const queue = [
          { url: '/api/test/1' },
          { url: '/api/test/2' },
          { url: '/api/test/3' },
          { url: '/api/test/4' },
        ];
    
    Promise.each(queue, (req) => {
        return http$({method: 'get', url: req.url}).then((resp) => {
                console.log(resp);
            });
    }).then(() => {
        console.log("done");
    }).catch(err => {
       console.error(err);
    })
    

    【讨论】:

      【解决方案2】:

      你需要的是承诺链和递归。

      const steps = [
          { url: '/api/test/1' },
          { url: '/api/test/2' },
          { url: '/api/test/3' },
          { url: '/api/test/4' },
      ]
      
      const executeStep = index => {
          // Validate step existence
          if (typeof steps[index] == 'undefined') return true;
          // Request
          return $http({method: 'get', url: steps[index].url})
          .then(response => {
              if (!response.success) throw response
              return executeStep(index+1)
          })
      }
      
      executeStep(0)
        .then( () => console.log('all done'))
        .catch(e => console.error('something failed', e))

      在这里,每次请求完成时,它都会返回一个包含下一个请求的新承诺。这样executeStep(0) 将仅在所有其他 Promise 完成时才被解析,或者如果任何 Promise 遇到错误,它将立即被拒绝。

      【讨论】:

        【解决方案3】:

        您可以将异步函数与 Promise 结合使用。

        const queue = [
          { url: '/api/test/1' },
          { url: '/api/test/2' },
          { url: '/api/test/3' },
          { url: '/api/test/4' },
        ];
        
        function oneRequest(req) {
            return new Promise((resolve,reject)=>{
                $http({method: 'get', url: req.url})
                    .success(response => resolve(response))
                    .error(err => reject(err));
            });
        }
        
        async function allRequests(reqs) {
            let resps = [];
            for(var i=0;i<reqs.length;i++) {
                let resp = await oneRequest(reqs[i]);
                resps.push(resp);
            }
            return resps;
        }
        
        allRequests(queue)
            .then(resps => console.log(resps))
            .catch(err => console.log(err));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          • 2022-12-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多