简体   繁体   English

如何对数组中的每个文件发出POST请求

[英]How to make a POST request for each file in array

I have an array of drag'n'dropped files inside angular component. 我在angular组件中有一个拖放文件数组。 I would like to make a POST request to http://some.url for each of them. 我想对它们每个发出POST请求到http://some.url I'm trying to do the following: 我正在尝试执行以下操作:

drop.component.ts drop.component.ts

public drop(event) {  
    * somehow set droppedFiles *

    let observables = [];

    this.droppedFiles.forEach(file => observables.push(this.uploadFile(file)));
    forkJoin(observables); 
}  

public uploadFile(image) {
    return this.imagesService.saveImage(image, this.tigerId).pipe(first()).subscribe(
        (data: ISaveImageResponse) => {
            console.log(data);

            return;
        },
        error => {
            console.error(error);

            return;
        }
    );
}

images.service.ts images.service.ts

public saveImage(image: File): Observable<ISaveImageResponse> {
    let imageInfo = {
        name: null, type: null, image: null
    };

    imageInfo.name = [image.name, Validators.required];
    imageInfo.type = [image.type, Validators.required];
    imageInfo.image = null;

    let form = this.formBuilder.group(imageInfo);
    form.get('image').setValue(image);

    const formModel = this.prepareFormData(form);

    return this.http.post<any>(
        'http://some.url',
        formModel
    ).pipe(
        map((imageInfo: any) => {
            return imageInfo
        }),
        catchError((error, caught) => {
            return EMPTY;
        })
    );
}

If I drop single file, this works fine. 如果我删除单个文件,则工作正常。 But if there are multiple files, requests become pending but I can't see them logged to server (which is express.js server). 但是,如果有多个文件,请求将变为挂起状态,但我看不到它们已记录到服务器(即express.js服务器)中。
What is the problem? 问题是什么?

UPDATE 更新

I've updated code to be actual: now uploadImage() returns Observable and requests are called from forkJoin() 我已经将代码更新为实际的代码:现在uploadImage()返回Observable并从forkJoin()调用请求

UPDATE 2 更新2

Chrome开发工具

After some time requests being pending I get the following error in server console: 经过一段时间的请求待处理后,服务器控制台中出现以下错误:

(node:1291) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 
11 field listeners added. Use emitter.setMaxListeners() to increase limit  

But no info about request happening at all (for any request I do, for example console.log('POST /images'); ) 但是根本没有关于请求的信息发生(对于我所做的任何请求,例如console.log('POST /images');

UPDATE 3 更新3

server-side code for handling POST requests: 用于处理POST请求的服务器端代码:

server.js server.js

const server = express();
const fs = require("fs");
const path = require('path');
const passport = require('passport');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);

server.use(
    session({
        store: new RedisStore({
            url: config.redisStore.url
        }),
        secret: config.redisStore.secret,
        resave: false,
        saveUninitialized: false
    })
);
server.use( passport.initialize() );
server.use( passport.session() );
server.use( cors({ origin: '*' }) );
server.use( bp.json() );
server.use( express.static('uploads') );
server.use( require('./image.routes') );

const port = 9901;

server.listen(port, () => {
    const dir = __dirname + '/uploads';
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir);
    }
    console.log('We are live on ' + port);
});  

image.routes.js image.routes.js

const fs = require('fs');
const formidable = require('express-formidable');
const path = require('path');
let router = express.Router();

router.post('/images',
    formidable({
        encoding: 'utf-8',
        uploadDir: path.resolve(__dirname, 'uploads'),
        multiples: true,
        keepExtensions: true
    }),
    (req, res, next) => {
        console.log('\nPOST /images');

        const image = req.fields;
        const data = req.files;

        image.path = data.image.path;

        const file = fs.createReadStream(image.path);

        createImage(image).then(  // createImage() saves image info to db
            result => {
                if (result) {
                    res.status(200).send(result);
                } else {
                    console.error("Cannot save image");
                    res.status(400).send("Cannot save image");
                }
        }).catch(e => console.error(e.stack));
});  

module.exports = router;

You cant use Promise.all to handle Rxjs requests. 您不能使用Promise.all处理Rxjs请求。

You can use forkJoin to make multiple Observale request at once, 您可以使用forkJoin一次发出多个Observale请求,

public drop(event) {  
* somehow set droppedFiles *

   let observables = []

   this.droppedFiles.forEach(file => observables.push(this.uploadFile(file)));
   Rx.Observable.forkJoin(observables)
} 

Also your uploadFile function is not returning an observable 而且您的uploadFile函数没有返回可观察到的

   public uploadFile(image) {
      return this.imagesService.saveImage(image, this.tigerId).pipe(first())
   }

check out example number 5 here 在此处查看示例5

Try using 'map' or 'for' instead forEach. 尝试使用“ map”或“ for”代替forEach。

public drop(event) {  
    * somehow set droppedFiles *

    Promise.all(this.droppedFiles.map(file => this.uploadFile(file))); 
}  

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

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