2016-06-13 12 views
0

Ich benutze eine forkJoin von Observablen, aber ich habe Probleme, Argumente in meinem Observables zu übergeben. im Wert von Codezeilen mehr als tausend Worte:Pass Argumente in Array von Observablen

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'); 
    } 
); 

(ich habe den Code für eine bessere Klarheit vereinfacht)

Wie man hier sehen kann, das Problem ist, dass, wenn der Code die Observablen ausführt, die pdf Variable gleich der letzten pdfObjects anstatt eine andere Variable für jede Observable zu sein.

Die Frage ist, wie kann ich meine pdf Variable "weitergeben" und "kopieren", so dass es ein Unterschied für jedes Observable ist?

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

bearbeiten

Ihr Problem ist die Verwendung von Verschlüssen innerhalb von Schleifen bezogen werden:

+0

Meinen Sie, den Wert mit Klammern im Let zu umgeben, ein neues Objekt mit einem Schlüssel von 'pdfObjects' zu erstellen, oder ist das ein Tippfehler bei der Vereinfachung? –

Antwort

3

Sie sollten die next Methode anstelle der complete ein Anruf.

könnten Sie mit einer Methode brechen:

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)); 
    } 
    (...) 
} 

diese Frage finden Sie weitere Details:

dieses plunkr Siehe: https://plnkr.co/edit/P4BfwnA1HEw7KU4i3RbN?p=preview.

+0

Danke, aber es löst das Problem nicht hier ... 'observer.next()' wird einfach den PDF-Wert im 'subscribe' von' forkJoin' zurückgeben! Was ich brauche ist, dass jedes Observable eine eigene 'pdf'-Variable als Argument hat. – ncohen

+0

Ich denke, dass Ihr Problem mit der Verwendung von Verschlüssen in Schleifen zusammenhängt. Ich habe meine Antwort entsprechend aktualisiert ... –

+0

Werden die Observablen ein anderes 'pdf'-Argument haben? Das Problem, das ich sehe, ist, dass Sie die Funktion mit einer 'pdf'-Referenz drücken und diese Referenz sich ändern wird (sie wird gleich dem letzten pdfObjects-Element sein), wenn sie von' forkJoin' ausgeführt wird. – ncohen

0

@Thierry ist richtig, hier ein Beispiel zu zeigen, was auf (fiddle) geht

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)); 
} 

Ergebnis:

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 

Wenn createObservable genannt wird, jeder Wert ist, wie man erwarten würde. Aber wenn Sie Ihre Observables abonnieren, wird die anonyme Funktion, die observer dauert, von RxJs aufgerufen und verwendet die aktuellen Werte für pdf und key, die das waren, was sie das letzte Mal durch die Schleife waren. Da Sie jedoch eine Funktion erstellen, gibt es einen neuen Bereich und das Argument 'p' in diesem Bereich ist der Wert, mit dem die Funktion aufgerufen wurde.