2015-10-20 43 views
5

Mam dziwny błąd, który czasami pojawia się w mojej aplikacji WinJS na emulatorze RAM Windows Phone 8.1 512 MB. Nie mogłem odtworzyć go w innych instancjach Emulatora lub na urządzeniu.WinJS: Łańcuch obietnicy czasami trzyma się po użyciu klasy BackgroundUploader na 512 MB WinPhone 8.1 Emu

Realizacja przebiega łańcucha obietnicy i kończy następujące return:

return (currentUpload = uploadOperation.startAsync()); 

Po że nic się nie dzieje. Ustawiam punkty przerwania dla wszystkich trzech funkcji (sukces, niepowodzenie, oczekiwanie), które są podane w definicji .then. Żaden z tych trzech kodów funkcji nigdy nie zostanie osiągnięty, gdy pojawi się ten dziwny przypadek.

Umieściłem także to oświadczenie zwrotu na bloku catch próby, ale nie było wyjątku do połowu.

krótkie wyjaśnienie kodu: jest tworzony

  • Tło instancja Uploader (nagłówki niestandardowe + metody PUT)

  • StorageFile jest otwarty przez URI

  • uploader Tło sporządza przesłać tego pliku (definicja uploadOperation)

  • Funkcja uploadOperation zostanie uruchomiona

zobaczyć pełny kod:

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

dzięki za pomoc!

P.S. Dostałam też przestarzałej ostrzeżenie, chociaż nie używam grupy/TransferGroup od klasy BackgroundUploader:

Sposób Windows.Networking.BackgroundTransfer.IBackgroundTransferBase.put_Group została zaniechana. Grupa może być zmieniona lub niedostępna dla wersji po Windows 8.1. Zamiast tego użyj TransferGroup.

Być może jest to związane z tym obietnicą błędu łańcucha.

+1

Szczerze mówiąc, nie rozumiem, co próbujesz osiągnąć za pomocą 'return (currentUpload = uploadOperation.startAsync());'. Poza tym zawiedliście, obiecując łańcuch. Podczas łączenia obietnic, obsługa błędów musi zostać wykonana na końcu i dla wszystkich. To piękno obietnicy przykuwającej uwagę. – sebagomez

+0

Ta instrukcja zapisuje bieżące przesłanie w zmiennej globalnej. Wyobraź sobie, że będzie to powrót uploadOperation.startAsync() - przetestował go, wystąpił również błąd. Co masz na myśli mówiąc "pomieszany"? Czy mówisz o najlepszej praktyce i stylu, czy może to prowadzić do błędu? Powód, dla którego zrobiłem to, co to tylko dało mi "błąd WinRT", więc nie mogłem prawidłowo rozróżnić błędów (jest tekst, ale jest to związane z określonym językiem). – kerosene

+0

Zgodnie z [Dokumentacją MSDN] (https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation.startasync.aspx) ta funkcja może obniżyć wydajność. Być może doświadczasz spowolnienia. Zalecają "wywołanie funkcji StartAsync w wątku pracującym w tle ..." Czy to może być źródłem Twojego problemu? – Jimmy

Odpowiedz

2

Może prosty błąd literowy?
Wystarczy sprawdzić komentarze w kodzie s poniżej

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 ??? 
*/ 

może ona stracić część swojego kodu, aby mieć pewność, że ponieważ w tym stanie, kod musi złamać!


Może adjustement mogą być:

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

Patrząc dalej (i nie używać winjs), jest coś do wyjaśnienia:

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

gdzie to ustawiasz:
currentUpload = 'Canceled'
Sprawdzasz to, ale jestem pewien, że ta część kodu nigdy nie zostanie osiągnięta.
Wcześniej swój odrzucić swoją obietnicę:
return WinJS.Promise.wrapError('file not found');
może następnym then powinien obsługiwać cos takiego:

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

Mam nadzieję, że to pomoże.

+0

dzięki za odpowiedź. funkcja oczekująca (status) jest funkcją postępu. 'promise.then (onComplete, onError, onProgress) .done (/ * Twój program do obsługi sukcesu i obsługi błędów * /);' [ms docu] (https://msdn.microsoft.com/de-de/library/windows /apps/br229728.aspx) Myślę, że .catch() nie jest dostępny na WinJS - przynajmniej nie mogłem znaleźć żadnej dokumentacji. Myślę, że funkcja niepowodzenia na .done powinna wykonać tę pracę. Próbowałem już je zdefiniować, ale błąd nadal występuje. – kerosene

+1

Mam zaktualizowaną odpowiedź, myślę, że masz podwójną klamrę zamykającą w niewłaściwym miejscu, które prowadzi do tego złego zachowania – Anonymous0day

+1

Po raz kolejny zmodyfikowałem swoją odpowiedź, po prostu sprawdzam komentarze, szczególnie część o funkcji (uploadOperation) ' – Anonymous0day