【问题标题】:Pass arguments into array of observables将参数传递给 observables 数组
【发布时间】:2016-06-13 05:26:34
【问题描述】:

我正在使用 forkJoin 的 observables,但在我的 observables 中传递参数时遇到了麻烦。一千字的代码行数:

for(var key in pdfObjects){
    let pdf = {pdfObjects[key]};
    observables.push(new Observable(observer => {
        this.createPDF(pdf).subscribe((pdfFile) => {
            // Do something with my pdfFile
            observer.complete();
        })
    })
}
Observable.forkJoin(observables).subscribe(
    (next) => {},
    (error) => {},
    (completed) => {
        console.log('completed');
    }
);

(为了更清晰,我已经简化了代码)

正如您在此处看到的,问题在于当代码执行 observable 时,pdf 变量等于最后一个 pdfObjects,而不是每个 observable 的不同变量。

问题是如何“传递”和“复制”我的 pdf 变量,以便每个可观察变量都不同?

【问题讨论】:

  • 您的意思是在 let 中用括号将值括起来,创建一个键为 'pdfObjects' 的新对象,还是简化时的拼写错误?

标签: javascript angular rxjs observable


【解决方案1】:

您应该调用next 方法而不是complete 方法:

observables.push(new Observable(observer => {
  this.createPDF(pdf).subscribe((pdfFile) => {
    // Do something with my pdfFile
    observer.next(pdf); // <-----
  });
})

编辑

您的问题与在循环中使用闭包有关。

你可以用一个方法打破:

createObservable(pdf:any) {
  return new Observable(observer => {
    this.createPDF(pdf).subscribe((pdfFile) => {
      // Do something with my pdfFile
      observer.complete();
    });
  });
}

otherMethod() {
  for(var key in pdfObjects){
    let pdf = {pdfObjects[key]};
    observables.push(this.createObservable(pdf));
  }
  (...)
}

查看这个问题了解更多详情:

看到这个 plunkr:https://plnkr.co/edit/P4BfwnA1HEw7KU4i3RbN?p=preview

【讨论】:

  • 谢谢,但这并不能解决这里的问题...observer.next() 只会返回forkJoinsubscribe 中的pdf 值!我需要的是每个 observable 都有自己的 pdf 变量作为它的参数。
  • 我认为您的问题与在循环中使用闭包有关。我相应地更新了我的答案......
  • observables 会有不同的pdf 参数吗?我看到的问题是您正在使用 pdf 引用推送函数,并且当 forkJoin 执行该引用时,该引用将发生变化(它将等于最后一个 pdfObjects 项)。
  • 我错过了什么吗?
  • 事实上,在这种情况下,变量不会绑定到内部函数之外的变量(你的问题)。我在答案中添加了一个 plunkr ;-)
【解决方案2】:

@Thierry 是对的,这里有一个例子来说明正在发生的事情 (fiddle)

var pdfObjects = {
  a: 'Object A',
  b: 'Object B',
  c: 'Object C'
};

for(let key in pdfObjects) {
  let pdf = pdfObjects[key];
  function createObservable(p) {
    console.log('createObservable:', p, pdf, key);
    return Rx.Observable.create(observer => {
      console.log('createObservable.create:', p, pdf, key);
      observer.onNext({ p: p, pdf: pdf, key: key});
      observer.onCompleted();
    });
  }
  observables.push(createObservable(pdf));
}

结果:

createObservable: Object A Object A a
createObservable: Object B Object B b
createObservable: Object C Object C c
createObservable.create: Object A Object C c
createObservable.create: Object B Object C c
createObservable.create: Object C Object C c

createObservable 被调用时,每个值都和你期望的一样。但是当你订阅你的 observables 时,接受 observer 的匿名函数被 RxJs 调用,并使用 pdfkey 的当前值,这是它们最后一次通过循环的值。但是因为您正在创建一个函数,所以有一个新的作用域,并且该作用域中的参数“p”是调用该函数的值。

【讨论】:

    猜你喜欢
    • 2017-05-28
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多