2015-10-20 15 views
5

我的Windows Phone 8.1 512MB RAM模拟器上的WinJS应用程序有时会出现奇怪的错误。我无法在其他Emulator实例或设备上重现它。WinJS:Promise链有时会在使用512MB的BackgroundUploader类后粘住WinPhone8.1 Emu

执行贯穿承诺链,并完成以下return语句:

return (currentUpload = uploadOperation.startAsync()); 

后没有任何反应。 我在赋予.then定义的所有三个函数(成功,失败,挂起)中设置了断点。当这种奇怪的情况发生时,这三种功能代码都不会达到。

我也把这个返回语句放在一个try catch块上,但是没有例外。

的代码简短说明:

  • 背景上传器实例被创建(自定义标头+ PUT方法)

  • StorageFile由URI

    打开
  • 背景载准备上载该文件的(定义uploadOperation)

  • uploadOperation将开始

看到全码:

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

感谢您的帮助!

P.S.我也有一个过时的警告,虽然我没有使用上BackgroundUploader类组/ TransferGroup:

Windows.Networking.BackgroundTransfer.IBackgroundTransferBase.put_Group 已被废弃的方法。在Windows 8.1之后,组可能会被更改或无法使用版本 。而是使用TransferGroup。

也许它是与承诺链错误有关。

+1

我坦率地不明白你想用'return(currentUpload = uploadOperation.startAsync());'实现。你也搞砸了你承诺链接。当链接承诺时,我必须在最后完成错误处理和所有错误处理。这就是承诺链的美妙之处。 – sebagomez

+0

该声明将当前上载保存在全局变量中。想象一下,它会返回uploadOperation.startAsync() - 测试它,然后出错。 “搞砸”是什么意思?你是在谈论最佳做法和风格,还是可能导致错误?我这样做的原因是它只给了我一个“WinRT错误”,所以我无法正确区分这些错误(有一个文本,但这是一种特定的语言)。 – kerosene

+0

根据[MSDN文档](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.downloadoperation.startasync.aspx),该函数可能会降低性能。也许你正在经历一个放缓。他们建议“你在后台工作线程上调用StartAsync ...”这可能是你问题的根源吗? – Jimmy

回答

2

也许是一个简单的错字错误?
只需选中注释代码小号下面

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

也许是想念你的代码的一部分,以确保这一点,因为在这种状态下你的代码必须打破!


也许一个adjustement可能是:

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

    } 
); 
} 

编辑

寻找进一步(我不使用winjs),有一些需要澄清:

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

你在哪里设置:
currentUpload = 'Canceled'
你正在检查,但我很确定这部分代码是永远不会到达的。
在此之前,你拒绝与你的承诺:
return WinJS.Promise.wrapError('file not found');
说不定下then应该处理成才这样的:

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

我希望这会帮助你。

+0

感谢您的回答。待处理(状态)功能是一个进度功能。 (onComplete,onError,onProgress).done(/ *您的成功和错误处理程序* /);' [ms docu](https://msdn.microsoft.com/de-de/library/windows /apps/br229728.aspx)我认为.catch()在WinJS上不可用 - 至少我找不到任何文档。我认为.done部分的失败功能应该可以完成这项工作。我已经试着去定义它们,但是仍然会出现错误。 – kerosene

+1

我已经更新了我的答案,我认为你有一个双重右大括号在错误的地方导致这种不良行为 – Anonymous0day

+1

我再一次修改了我的答案,只是检查注释,特别是有关'function(uploadOperation) ' – Anonymous0day