简体   繁体   English

如何在 Angular $http 中处理来自 Express response.write() 的响应

[英]How to handle response from Express response.write() in Angular $http

I'm trying to upload a csv file using ng-file-upoad .我正在尝试使用ng-file-upoad上传 csv 文件。 Here is my code snippet:这是我的代码片段:

Upload.upload({
   url: baseUrl + '/file-upload',
   data: {
      file: file
   }
 })
 .then(function(res) {
    console.log('success: ===> ', res);
 }, function(err) {
    console.log('erroir: ===> ', err);
 }, function() {
    console.log('progress: ', arguments);
 });

And in node environment I'm parsing the file and inserting the data in database.在节点环境中,我正在解析文件并将数据插入数据库。 I don't want to close the connection.我不想关闭连接。 That's why I used "response.write".这就是我使用“response.write”的原因。 Here is my code snippet:这是我的代码片段:

var path = req.files.file.path,
    currentIndex = 0;

fs.readFile(path, 'utf8', function(err, data) { 
    if(err) {
         // handle error
    } else {
        // making array (dataArray) from data
        dataArray.forEach(function(eachData){
            newEntry = new app.db.models.SomeCollection(eachData);
            newEntry.save(function(err, data) {
              if (currentIndex === dataArray.length) {
                 res.end('DONE!');
              } else {
                  currentIndex++;
                  res.write(JSON.stringify({
                     total: dataArray.length,
                     done: currentIndex
                  }));
              }
            });
        })
    }
});

My question is how I will get the data I'm passing in "res.write"?我的问题是如何获取我在“res.write”中传递的数据? I don't want to use socket for only this purpose.我不想仅将套接字用于此目的。 Am I missing something?我错过了什么吗?

As already explained here : 正如这里已经解释的:

response.send(msg) is equal to response.write(msg);response.end(); response.send(msg)等于response.write(msg); response.end();

Which means, send can only be called once, write can be called many times, but you must call end yourself. 这意味着,发送只能被调用一次,写入可以被多次调用,但是您必须自己结束。

You are probably not receiving the response because response.end() is missing. 您可能没有收到响应,因为缺少response.end()

Once you end() your response you should be able to access the response data in your angular controller in the Upload.upload promise that is returned. 一旦end()响应,您就应该能够在返回的Upload.upload承诺中的角度控制器中访问响应数据。

It's not like close a connection as you said. 就像您说的那样,这不像关闭连接 This is not a socket-ish like implementation (such as ws or socket.io ). 这不是类似套接字的实现(例如wssocket.io )。 Once a request is made it should have a response even if it is to provide error details about that request (ie status 401, 403, 404, etc). 提出请求后,即使要提供有关该请求的错误详细信息(即状态401、403、404等),它也应具有响应。

in your angular component:在您的 angular 组件中:

  ...
  constructor(private incrementalService: IncrementalService) {}
   
  incrementalTest() { //activate with a button or whatnot
    this.incrementalService.increment().subscribe( (result:any) => {
      if (result.partialText) {
        console.log(partialText); //do whatever you need to do with your partial results here!
      }
    })
  }

your angular service:您的 angular 服务:

   import { HttpClient, HttpHeaders } from '@angular/common/http';
   public class IncrementalService {

     constructor(private http: HttpClient) {}

     increment(): Observable<ArrayBuffer> {
        const options = {
          reportProgress: true,
          responseType: 'text',
          observe: 'events'
        }
        return this.http.request('get', 'http://someURL', { ...this.addRawHeaderOptions(), ...options});
     }

     private addRawHeaderOptions() {
        const authHeaders = new HttpHeaders({
          'Content-Type': 'text/html',
          //authorization, Cache-Control: 'no-cache, Pragma:'no-cache', et al.     }
        return { headers: authHeaders }
     }
   }

Finally, your back-end service (this is express, but should work similarly for raw node):最后,您的后端服务(这是快速的,但对于原始节点应该类似地工作):

  async function(request, response) {
    const increments = [ 1,2,3,4 ];
    response.set('Content-Type', 'text/html');
    for (const value of increments) { //contains async call - not switch-outable for a forEach.
      response.write(`increment - ${value} `);
      const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
      await delay(1000)
    }
    response.status(200).end()
  }

browser console output when run:浏览器控制台 output 运行时:

  • increment - 1增量 - 1
  • increment - 1 increment - 2增量 - 1 增量 - 2
  • increment - 1 increment - 2 increment - 3增量 - 1 增量 - 2 增量 - 3
  • increment - 1 increment - 2 increment - 3 increment - 4增量 - 1 增量 - 2 增量 - 3 增量 - 4

.!Sorry for any typos - i had to transcribe this from a locked-down machine. .!抱歉有任何错别字——我不得不从一台锁定的机器上转录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM