不一致的mergeMap行为

时间:2018-09-12 08:47:45

标签: javascript ajax rxjs rxjs6

我目前正在研究一种文件上传方法,该方法要求我限制通过的并发请求的数量。

我首先编写了一个应如何处理的原型

const items = Array.from({ length: 50 }).map((_, n) => n);
from(items)
  .pipe(
    mergeMap(n => {
      return of(n).pipe(delay(2000));
    }, 5)
  )
  .subscribe(n => {
    console.log(n);
  });

它确实起作用了,但是当我将of换成实际的电话时,它就起作用了。它只处理一个块,所以说20个文件中有5个

from(files)
  .pipe(mergeMap(handleFile, 5))
  .subscribe(console.log);

handleFile函数返回对自定义ajax实现的调用

import { Observable, Subscriber } from 'rxjs';
import axios from 'axios';

const { CancelToken } = axios;

class AjaxSubscriber extends Subscriber {
  constructor(destination, settings) {
    super(destination);
    this.send(settings);
  }

  send(settings) {
    const cancelToken = new CancelToken(cancel => {
      // An executor function receives a cancel function as a parameter
      this.cancel = cancel;
    });
    axios(Object.assign({ cancelToken }, settings))
      .then(resp => this.next([null, resp.data]))
      .catch(e => this.next([e, null]));
  }

  next(config) {
    this.done = true;
    const { destination } = this;
    destination.next(config);
  }

  unsubscribe() {
    if (this.cancel) {
      this.cancel();
    }
    super.unsubscribe();
  }
}

export class AjaxObservable extends Observable {
  static create(settings) {
    return new AjaxObservable(settings);
  }

  constructor(settings) {
    super();
    this.settings = settings;
  }

  _subscribe(subscriber) {
    return new AjaxSubscriber(subscriber, this.settings);
  }
}

所以看起来像这样

function handleFile() {
  return AjaxObservable.create({
    url: "https://jsonplaceholder.typicode.com/todos/1"
  });
}

CodeSandbox

如果我从合并映射函数中删除并发参数,则一切正常,但会一次全部上传所有文件。有什么办法可以解决这个问题?

1 个答案:

答案 0 :(得分:0)

原来的问题是我没有在0x8A 0x01内调用complete()方法,所以我将代码修改为:

AjaxSubscriber

然后通过axios调用:

pass(response) {
  this.next(response);
  this.complete();
}