我怎样才能从一个长期的asynchronous过程接收实时更新?

我正在写一个小型的内部Web应用程序,读取表单数据并创build一个Excel文件,然后通过电子邮件发送给用户。

但是,我正在努力了解如何在完成过程时为用户实现实时更新。 有时这个过程需要10秒,有时这个过程需要5分钟。

目前,用户一直等到stream程完成,然后才能看到任何结果 – 当stream程正在完成时,他们没有看到任何更新。 在显示报告信息之前,前端等待来自服务器的201响应 ,并且用户被“阻止”,直到RC完成。

我很难理解如何asynchronous启动报告创build(RC)过程,同时允许用户导航到网站的其他页面。 或者看到在后台发生的更新。 我在此应该澄清一下,RC过程中的一些步骤使用Promises。

我想每秒轮询一次服务器,以获得正在生成的报告的更新。

这里有一些简单的代码来澄清我的理解:

端点

// CREATE REPORT router.route('/report') .post(function(req, res, next) { // Generate unique ID to keep track of report later on. const uid = generateRandomID(); // Start report process ... this should keep executing even after a response (201) is returned. CustomReportLibrary.createNewReport(req.formData, uid); // Respond with a successful creation. res.status(201); } } // GET REPORT router.route('/report/:id') .get(function(req, res, next){ // Get our report from ID. let report = CustomReportLibrary.getReport(req.params.id); // Respond with report data if(report) { res.status(200).json(report); } else { res.status(404); } } 

CustomReportLibrary

 // Initialize array to hold reports let _dataStorage = []; function createNewReport(data, id) { // Create an object to store our report information let reportObject = { id: id, status: 'Report has started the process', data: data } // Add new report to global array. _dataStorage.push(reportObject); // ... continue with report generation. Assume this takes 5 minutes. // ... // ... update _dataStorage[length-1].status after each step // ... // ... finish generation. } function getReport(id) { // Iterate through array until report with matching ID is found. // Return report if match is found. // Return null if no match is found. } 

根据我的理解,即使在返回201响应之后, CustomerReportLibrary.createNewReport()也会在后台执行。 在前端,我会间歇性地对/report/:id进行AJAX调用,以获取我的报告的更新。 这是正确的方法吗? 有一个更好的方法吗?

我想你是对的。 HTTP 202(请求已被接受处理,但处理尚未完成)是处理您的情况的正确方法。

可以这样做:

  1. 客户端发送POST /reports ,服务器开始创build新的报告并返回:

     202 Accepted Location: http://api.domain.com/reports/1 
  2. 客户端发出GET /reports/1来获取报告的状态

以上所有stream程都是asynchronous的,所以用户不会被阻止。