2017-05-20 6 views
1

I Funktion wie diese haben, ist es nur laden Bild mit xhr Anfrage:Wie beobachtbare zurückzukehren, von xhr

public uploadAvatar(avatarFile, callback) { 
    return new Promise((resolve, reject) => { 
     let formData: any = new FormData(); 
     let url = 'avatar'; 
     let imgArr = "avatar"; 
     let xhr = new XMLHttpRequest(); 

     formData.append(imgArr, avatarFile, avatarFile.name); 
     xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      if (xhr.status == 200) { 
      resolve(JSON.parse(xhr.response)); 
      callback('success'); 
      } else { 
      reject(xhr.response); 
      callback('error'); 
      } 
     } 
     }; 

     xhr.open("POST", environment.baseUrl + url, true); 
     xhr.setRequestHeader('Auth', this._auth.getToken()); 
     xhr.send(formData); 
    }); 
    } 

Wie kann ich beobachtbare zurückkehren insted Versprechen?

Antwort

0

So etwas sollte

public uploadAvatar(avatarFile, callback) { 
    return Rx.Observable.create(function (observer) { 
     let formData: any = new FormData(); 
     let url = 'avatar'; 
     let imgArr = "avatar"; 
     let xhr = new XMLHttpRequest(); 

     formData.append(imgArr, avatarFile, avatarFile.name); 
     xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      if (xhr.status == 200) { 
      observer.onNext(JSON.parse(xhr.response)); 
      observer.onCompleted(); 
      callback('success'); 
      } else { 
      observer.onError(xhr.response); 
      callback('error'); 
      } 
     } 
     }; 

     xhr.open("POST", environment.baseUrl + url, true); 
     xhr.setRequestHeader('Auth', this._auth.getToken()); 
     xhr.send(formData); 
    }); 
} 
0

eddyP23 arbeiten Antwort fast korrekt ist, aber es gibt noch zwei Dinge.

Ein wichtiger Unterschied zwischen Observables und Promises ist, dass Observables im Gegensatz zu Promises abgebrochen werden können. Dies ist sehr relevant für Ihre Situation, in der Sie XHR zum Ausführen von AJAX-Anrufen verwenden. Während XMLHttpRequest mit der abort() function abgebrochen werden kann, können Sie ausstehende Promise nicht abbrechen.

Aber mit Observables können Sie. Wenn Sie ein Observable abschließen oder abbestellen, können Sie das XHR-Objekt auch abbrechen, weil Sie wissen, dass Sie daran nicht interessiert sind.

Siehe auch: https://medium.com/@benlesh/promise-cancellation-is-dead-long-live-promise-cancellation-c6601f1f5082

So funktionieren Sie, wenn von der Verwendung Promises zu Observable verwandelt sollte wie folgt aussehen:

public uploadAvatar(avatarFile, callback) { 
    return Rx.Observable.create(function (observer) { 
     ... 
     xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      if (xhr.status == 200) { 
       observer.onNext(JSON.parse(xhr.response)); 
       observer.onCompleted(); 
      } else { 
       observer.onError(xhr.response); 
      } 
     } 

     return() => { 
      xhr.abort(); 
     }; 
    } 
) 

Beachten Sie, dass wir eine Funktion sind Rückkehr, die verwendet wird, wenn die beobachtbaren entsorgen. Für weitere Informationen über Observable.create werfen Sie einen Blick auf http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-create

Die zweite Sache ist, dass, wenn Sie nicht über den Abbruch der XHR wollen, können Sie nur Versprechen verwenden. RxJS 5 behandelt Promises genauso wie Observables. Beachten Sie, dass Observable.from() als Parameter einige ObservableInput, die hier im Detail beschrieben ist: http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObservableInputDoc.html

Für Sie bedeutet dies, dass Sie nur uploadAvatar() nennen kann, ist und das Versprechen zurückgegeben wird gedreht werden in eine Observable automatisch:

Observable.from(uploadAvatar(...)) 
    .subscribe(...) 
0

Verwenden Sie fromPromise in Ihrem Versprechen. Denken Sie daran, die Methode vorher zu importieren, z. B.

import 'rxjs/add/observable/fromPromise';