0

我想在这个级别上创建一个 Nestjs 的拦截器,并且想要上传文件。我找不到解决方案,如何通过 Observable 解决此代码(https://github.com/fastify/fastify-multipart

我正在使用 fromPromise 但使用此工具,我遇到了更多问题。因为我只能解决一次。我需要对每个文件进行验证,如果验证返回解析,则运行泵进行写入。

const mp = req.multipart(handler, function (err) {
    console.log('upload completed')
    reply.code(200).send()
  })
  // handler wil run for each file
  function handler (field, file, filename, encoding, mimetype) {
    // to accumulate the file in memory! Be careful!
    //
    // file.pipe(concat(function (buf) {
    //   console.log('received', filename, 'size', buf.length)
    // }))
    //
    // or

    pump(file, fs.createWriteStream('a-destination'))

    // be careful of permission issues on disk and not overwrite
    // sensitive files that could cause security risks
  }

我使用这个代码,对于我的旧案例来说就足够了......

const obs1$ = fromPromise(new Promise((res, rej) => {
            const mp = request.multipart((field, file, filename, encoding, mimetype) => {
                const writeStream = fs.createWriteStream('path');
                //here need run onValidation
                pump(file, writeStream);
            }, (err) => {
                //doSuccess
                (err) ? rej(err) : res();
            });
        }));

        return obs1$.pipe(
            catchError(error => {
                throw new BadRequestException(error);
            }),
            switchMap(() => {
                request.body = body;
                return next.handle();
            }), mergeAll());

但我有一个新案例(我需要在保存文件之前进行验证),案例是:next.hander() 使用一些方法返回 Observable:

@Controller('test')
export class TestCtrl {

@Post('upload')
@UseInterceptors(new FileInterceptor())
    uploadFile() {
        return {
            onValidate: (file: IFiles) => {
                console.log(this.tst);
                return Promise.resolve(true);
            },
            onSuccess: () => {
                return Promise.resolve(true);
            }
        };
    }
}

尝试过这样的事情:

@Injectable()
export class FileInterceptor implements NestInterceptor {

    intercept(context: any, next: CallHandler): Observable<any> {
        const request = context.getRequest();
        const body: Array<any> = [];

        return next.handle().pipe(switchMap((methods: any) => {
            const mp = request.multipart((field, file, filename, encoding, mimetype) => {
                const writeStream = fs.createWriteStream('path');
                body.push({
                    filename, file
                });

                methods.onValidation(file).then(() => {
                    pump(file, writeStream);
                }).catch(() => {
                    writeStream.destroy();
                });
            }, () => {
                //done
                methods.onSuccess(body); // how to return this?
            });
            return null; // ???
        }));

 }
}
4

1 回答 1

0

我几乎通过bindNodeCallback解决了我的问题,然后我编写了自己的 bindNodeCallback 方法,该方法可以通过双重回调解决我的问题。

callbackFunc.apply(context, [...args, handler1, handler2, handler3]);
于 2019-08-17T14:18:58.340 回答