首页 > 解决方案 > 如何使用 Promise 发送多个不同的请求,并且一个接一个地运行?

问题描述

我有这个脚本,用于将一些数据从 API 导入到我的数据库中。由于此过程非常耗时,因此它经常超时,因为在处理的某些项目上需要处理大量数据。

不久前我提出了这个解决方案,使用 Promise,首先向 API 发出请求,然后在完成后我会准备数据并将其放入临时 csv 文件中,然后我会发出另一个请求以将该文件拆分为多个较小的文件,然后......你明白了......它正在工作,但我需要添加一些额外的请求,我无法让它工作......我可能只需要简化我的逻辑。

任何人都可以帮助我改进此代码,以便更轻松地添加这些额外的请求并保持它一个接一个地发送一个请求?

这是有问题的(过度简化的)脚本:

window.importTrialsScripts = {};

window.addEventListener('DOMContentLoaded', function() {
  importTrialsScripts.app.initialize();
});

(function(importTrialsScripts, document, $) {
  importTrialsScripts = importTrialsScripts || {};

  const app = {
    ajaxurl: 'myajaxurl',

    initialize: function() {
      this.submitHandler();
    },

    submitHandler: function() {
      const self = this;

      document.querySelector('#start-import').addEventListener('click', function() {
        self.pullTrialsFromApi();
      });
    },

    pullTrialsFromApi: function() {
      let data = new FormData();
      data.append('action', 'pull_trials_from_api');

      [123, 456, 789].forEach(function(str) {
        data.append('ids[]', str);
      });

      this.startPullingTrials(data);
    },

    startPullingTrials: function(data) {
      const self = this;

      let promise = new Promise(function(resolve, reject) {
        self.sendAjaxRequest(data, function() {
          if (this.status === 200) {
            const response = JSON.parse(this.response);

            if (! response.success) {
              alert('The API could not be reached. Please try again.');
              console.error('Error!!', response);
              return;
            }

            resolve(response.data);
          }
          else {
            console.error('there was an error in the request', this);
            reject(this);
          }
        });
      });

      promise.then(function(chunks) {
        const processingChunks = Object.values(chunks).map(function(chunk) {
          return self.processChunk(chunk);
        });

        Promise.all(processingChunks).then(function (processedTrials) {
          console.log('finished', processedTrials);
        });
      }, function(err) {
        console.error('promise rejected', err);
      });
    },

    processChunk: function(chunkTrials) {
      const self = this;

      let data = new FormData();
      data.append('action', 'process_trials_chunk');

      Object.values(chunkTrials).forEach(function(chunk) {
        data.append('chunk[]', JSON.stringify(chunk));
      });

      return new Promise(function(resolve, reject) {
        self.sendAjaxRequest(data, function() {
          if (this.status === 200) {
            const response = JSON.parse(this.response);

            if (! response.success) {
              console.error('Error!!', response.data);
              return;
            }

            resolve(response.data);
          }
          else {
            console.log('there was an error in the request', this);
            reject(this);
          }
        });
      });
    },

    splitToMultipleFiles: function() {
      const self = this;

      const data = new FormData();
      data.append('action', 'split_location_files');

      return new Promise(function(resolve, reject) {
        self.sendAjaxRequest(data, function() {
          if (this.status === 200) {
            const response = JSON.parse(this.response);

            if ( ! response.success ) {
              console.error('Error!!', response.data);
              return;
            }

            resolve(response.data.files);
          }
          else {
            console.log('there was an error in the request', this);
            reject(this);
          }
        });
      });
    },

    processLocation: function(file) {
      const self = this;

      let data = new FormData();
      data.append('action', 'process_location_data');
      data.append('file', file);

      return new Promise(function(resolve, reject) {
        self.sendAjaxRequest(data, function() {
          if ( this.status === 200 ) {
            const response = JSON.parse(this.response);

            if (! response.success) {
              console.error('Error!!', response.data);
              return;
            }

            resolve(response.data);
          }
          else {
            console.log('there was an error in the request', this);
            reject(this);
          }
        });
      });
    },

    sendAjaxRequest: function(data, callback) {
      const self = this;

      let xhr = new XMLHttpRequest();
      xhr.open('POST', ajaxurl);

      xhr.onload = callback;

      xhr.addEventListener('timeout', function(e) {
        console.error('the request has timed out', e);
      });

      xhr.addEventListener('error', function(e) {
        console.error('the request returned an error', e);
      });

      xhr.addEventListener('abort', function(e) {
        console.error('the request was aborted', e);
      });

      xhr.send(data);
    },
  };

  $.extend(importTrialsScripts, {
    app: app
  });

}).apply(this, [window.importTrialsScripts, document, jQuery]);

标签: javascriptajaxpromise

解决方案


推荐阅读