2015-10-20 2 views
5

Ich habe seltsame Fehler, die manchmal auf meiner WinJS-App auf dem Windows Phone 8.1 512MB RAM-Emulator auftritt. Ich konnte es nicht auf anderen Emulator-Instanzen oder auf dem Gerät reproduzieren.WinJS: Promise-Kette klebt manchmal nach der Verwendung der BackgroundUploader-Klasse auf 512MB WinPhone8.1 Emu

Die Ausführung läuft durch die Versprechen Kette und beendet die folgende Anweisung return:

return (currentUpload = uploadOperation.startAsync()); 

Danach passiert nichts. Ich setze Haltepunkte bei allen drei Funktionen (Erfolg, Fehler, ausstehend), die der .then-Definition gegeben werden. Keiner dieser drei Funktionscodes wird jemals erreicht, wenn dieser seltsame Fall auftritt.

Ich habe auch diese Return-Anweisung auf einen Versuch Catch-Block, aber es gab keine Ausnahme zu fangen.

kurze Erklärung Code:

  • Hintergrund Uploader Instanz (benutzerdefinierte Header + PUT-Methode)

  • StorageFile von URI

    geöffnet Uploader dieser Datei laden prepares
  • Hintergrund erstellt (Definition von uploadOperation)

  • uploadOperation wird gestartet

siehe vollständigen Code:

var currentUpload; // global 

function uploadFile(localFullPath, headers, serverUrl) 
{ 
    var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath), 
     uploader = false; 

     try 
     { 
      uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader(); 
      uploader.method = 'PUT'; 

      // set headers to uploader 
      for (var key in headers) 
      { 
       if (headers.hasOwnProperty(key)) 
        uploader.setRequestHeader(key, headers[key]); 
      } 
     } 
     catch (e) 
     { 
      // error handling 
      return false; 
     } 

     Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri) 
     .then(function success(file) 
     { 
      return uploader.createUpload(serverUrl, file); 
     }, 
     function failure(error) 
     { 
      return WinJS.Promise.wrapError('file not found'); 
     }) 

     .then(function (uploadOperation) 
     { 
      if (currentUpload == 'Canceled') 
       return WinJS.Promise.wrapError('upload canceled'); 
      else 
       return (currentUpload = uploadOperation.startAsync()); 

     }) 

     .then(function success(success) 
     { 
      currentUpload = false; 
      // success handling 
      return true; 
     }, function failure(error) 
     { 
      currentUpload = false; 
      // error handling 
      return false; 
     } 

     }, function pending(status) 
     { 
      var progress = status.progress, 
       percent = Math.round(progress.bytesSent/progress.totalBytesToSend * 100); 

      // progress handling 
     }); 
     } 

Vielen Dank für jede Hilfe!

P.S. Ich habe auch eine veraltete Warnung, obwohl ich nicht Gruppe/TransferGroup auf der BackgroundUploader-Klasse:

Verfahren Windows.Networking.BackgroundTransfer.IBackgroundTransferBase.put_Group ist veraltet. Die Gruppe kann für die Versionen nach Windows 8.1 geändert oder nicht verfügbar sein. Verwenden Sie stattdessen TransferGroup.

Vielleicht ist es mit diesem Versprechen Kettenfehler verbunden.

+1

Offenbar verstehe ich nicht, was Sie mit 'return (currentUpload = uploadOperation.startAsync());' erreichen wollen. Auch du hast versaut, dass du Verkettung versprichst. Bei der Verkettung von Versprechungen muss die Fehlerbehandlung am Ende und für alle von ihnen durchgeführt werden. Das ist die Schönheit der Versprechensverkettung. – sebagomez

+0

Diese Anweisung speichert den aktuellen Upload in einer globalen Variablen. Stellen Sie sich vor, es wäre return uploadOperation.startAsync() - getestet, Fehler ist dann auch aufgetreten. Was meinst du mit "vermasselt"? Sprechen Sie über Best Practice und Style oder könnte dies zu einem Fehler führen? Der Grund, warum ich das gemacht habe, ist, dass es mir nur einen "WinRT-Fehler" gab, so dass ich die Fehler nicht richtig unterscheiden konnte (es gibt einen Text, aber dieser ist an eine bestimmte Sprache gebunden). – kerosene

+0

Gemäß der [MSDN-Dokumentation] (https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation.startasync.aspx) kann diese Funktion die Leistung beeinträchtigen. Vielleicht erleben Sie eine Verlangsamung. Sie empfehlen, "dass Sie StartAsync auf einem Hintergrund-Worker-Thread aufrufen ..." Könnte dies die Ursache Ihres Problems sein? – Jimmy

Antwort

2

Vielleicht ein einfacher Tippfehler ?? überprüfen
einfach die Kommentare in Code s unter

var currentUpload; // global 

function uploadFile(localFullPath, headers, serverUrl) 
{ 
    var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath), 
     uploader = false; 

     try 
     { 
      uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader(); 
      uploader.method = 'PUT'; 

      // set headers to uploader 
      for (var key in headers) 
      { 
       if (headers.hasOwnProperty(key)) 
        uploader.setRequestHeader(key, headers[key]); 
      } 
     } 
     catch (e) 
     { 
      // error handling 
      return false; 
     } 

     /* 

     return something it's a good practice if you want to chain Promises 
      | 
      | 
      V                  */ 
     return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri) 
     .then(
      function success(file){ 
      return uploader.createUpload(serverUrl, file); 
      }, 
      function failure(error){ 
      return WinJS.Promise.wrapError('file not found'); 
    //          |_____________| 
    // your are rejecting your promise with ---------^ 
      } 
     ).then(
      function (uploadOperation){ 

    // Just avoid this type of code construction 
    // and add brace ! 
    // adding brace augment readability and prevent errors ! 

      // where do you set this ??? currentUpload = 'Canceled' 
      // is part of winjs ??? 
      if (currentUpload == 'Canceled') 

      // why not handle your rejected promise ? 
      // by something like : 
      //if(uploadOperation == 'file not found') 
       return WinJS.Promise.wrapError('upload canceled'); 
      else 
       return (currentUpload = uploadOperation.startAsync()); 
      } 
     ).then(
// Promise resolve handler 
      function success(success){ 
      currentUpload = false; 
      // success handling 
      return true; 
      } , 
// Promise reject handler 
      function failure(error){ 
      currentUpload = false; 
      // error handling 
      return false; 
      } 
/*  ^ 
      | 
YOU HAVE HERE A DOUBLE CLOSING BRACE }} ??? 
° 
| WHAT IS THIS PART FOR ?????? 
| 
+------+---- Ending uploadFile with successive closing brace ! 
     | 
     |+---------------- Declaration separator 
     ||  +--- New function declaration 
     ||  | 
     VV  V      */ 
     }, function pending(status){ 
      var progress = status.progress, 
       percent = Math.round(progress.bytesSent/progress.totalBytesToSend * 100); 
      // progress handling 
     }); 
     } 

/* 
ALL THAT PART ABOVE IS NOT IN THE PROMISE CHAIN 
AND SHOULD BREAK YOUR CODE !!! 
HOW HAVE YOU EVER COULD RUN THIS ??? 
*/ 

vielleicht ist es ein Teil des Codes verpassen sicher davon zu sein, denn in diesem Zustand den Code brechen müssen!


Vielleicht könnte ein adjustement sein:

var currentUpload; // global 

function uploadFile(localFullPath, headers, serverUrl) 
{ 
    var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath), 
     uploader = false; 

    try 
    { 
    uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader(); 
    uploader.method = 'PUT'; 

    // set headers to uploader 
    for (var key in headers) 
    { 
     if (headers.hasOwnProperty(key)) 
     uploader.setRequestHeader(key, headers[key]); 
    } 
    } 
    catch (e) 
    { 
    // error handling 
    return false; 
    } 

    /* 

    return something it's a good practice if you want to chain Promises 
    | 
    | 
    V                  */ 
    return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri) 
    .then(
    function success(file){ 
     return uploader.createUpload(serverUrl, file); 
    }, 
    function failure(error){ 
     return WinJS.Promise.wrapError('file not found');// O|--------+ 
    }//                | 
).then(//               | 
    function (uploadOperation){// O|-------------------------------| 
     //               | 
     // Just avoid this type of code construction     | 
     // and add brace !           | 
     // adding brace augment readability and prevent errors !  | 
     //               | 
     // EDIT              | 
     //if (currentUpload == 'Canceled') { // <--- add brace  | 
     if (uploadOperation == 'file not found') { //<---add brace <--+ 

     return WinJS.Promise.wrapError('upload canceled'); 

     } else { // <---- add braces 

     // even if it is valid 
     // avoid assignement like that 
     // so subtil to read/understand/debug ... 
     // return (currentUpload = uploadOperation.startAsync()); 

     currentUpload = uploadOperation.startAsync(); 
     // maybe debug here ? 
     console.log('currentUpload : ' + currentUpload); 
     return currentUpload; 

     } // <---- add brace 
    } 
).then(
    function success(success){ 
     currentUpload = false; 
     // success handling 
     return true; 
    } , 
    function failure(error){ 
     currentUpload = false; 
     // error handling 
     return false; 
    } , 
    function pending(status){ 
     var progress = status.progress, 
      percent = Math.round(progress.bytesSent/progress.totalBytesToSend * 100); 
     // progress handling 
    } 
).done(// it is always a good thing to have a final catcher !! 
    function(){ 
     // things are ok ! 
     console.log('ok'); 
    }, 
    function(err){ 
     // make something with your error better than 
     alert(err); 
     console.log('ko'); 

    } 
); 
} 

EDIT

Suche weiter (i verwenden WinJS nicht), es etwas zu klären ist:

.then(
    function success(file) { 
    return uploader.createUpload(serverUrl, file); 
    }, 
    function failure(error) { 
    return WinJS.Promise.wrapError('file not found'); 

    } 
).then(
    function(uploadOperation) { 

    if (currentUpload == 'Canceled') 
     return WinJS.Promise.wrapError('upload canceled'); 
    else 
     return (currentUpload = uploadOperation.startAsync()); 
    } 
). 

wo setzen Sie diese Einstellung:
currentUpload = 'Canceled'
Sie überprüfen das, aber ich bin ziemlich sicher, dass dieser Teil des Codes nie erreicht wird.
Davor Sie ablehnen Ihr Versprechen mit:

.then(
    function success(file) { 
    return uploader.createUpload(serverUrl, file); 
    }, 
    function failure(error) { 
    return WinJS.Promise.wrapError('file not found'); 

    } 
).then(
    function(uploadOperation) { 

    if (uploadOperation == 'file not found') 
     return WinJS.Promise.wrapError('upload canceled'); 
    else 
     return (currentUpload = uploadOperation.startAsync()); 
    } 
) 

ich diese Ihnen helfen, hoffen:
return WinJS.Promise.wrapError('file not found');
vielleicht die nächsten then someting wie damit umgehen soll.

+0

danke für deine antwort. Die ausstehende (Status) Funktion ist eine Fortschrittsfunktion. 'promise.then (onComplete, onError, onProgress) .done (/ * Ihre Erfolgs- und Fehlerbehandlungsroutinen * /);' [ms docu] (https://msdn.microsoft.com/de-de/library/windows /apps/br229728.aspx) Ich denke, dass .catch() nicht auf WinJS verfügbar ist - zumindest konnte ich keine Dokumentation finden. Ich denke, dass eine Fehlfunktion auf dem .done-Teil diese Aufgabe übernehmen sollte. Ich habe bereits versucht, sie zu definieren, aber Fehler tritt immer noch auf. – kerosene

+1

Ich habe meine Antwort aktualisiert, ich denke, Sie haben eine doppelte schließende Klammer an der falschen Stelle, die zu diesem schlechten Verhalten – Anonymous0day

+1

führen Ich habe noch einmal meine Antwort geändert, überprüfen Sie einfach die Kommentare, insbesondere der Teil über 'function (uploadOperation) ' – Anonymous0day

Verwandte Themen