WinJS:在512MB WinPhone8.1 Emu上使用BackgroundUploader类后,Promise链有时会出现问题

ker*_*ene 5 javascript promise winjs windows-phone-8.1

我有一些奇怪的错误,有时会出现在我的Windows Phone 8.1 512MB RAM仿真器上的WinJS应用程序中.我无法在其他仿真器实例或设备上重现它.

执行通过promise链运行并完成以下return语句:

  return ( currentUpload = uploadOperation.startAsync() );
Run Code Online (Sandbox Code Playgroud)

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

我还把这个return语句放在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
        });
        }
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!

PS我也有一个弃用的警告,虽然我没有在BackgroundUploader类上使用group/TransferGroup:

不推荐使用Windows.Networking.BackgroundTransfer.IBackgroundTransferBase.put_Group方法.在Windows 8.1之后,组可能会被更改或不可用于发布.而是使用TransferGroup.

也许它与该承诺链错误有关.

Ano*_*day 2

也许是一个简单的拼写错误?\n只需检查下面代码
中的注释

\n\n
var currentUpload;  // global\n\n function uploadFile(localFullPath, headers, serverUrl)\n {\n    var fileUri = new Windows.Foundation.Uri(\'ms-appdata:///local\' + localFullPath),\n        uploader = false;\n\n        try\n        {\n            uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();\n            uploader.method = \'PUT\';\n\n            // set headers to uploader\n            for (var key in headers)\n            {\n                if (headers.hasOwnProperty(key))\n                    uploader.setRequestHeader(key, headers[key]);\n            }\n        }\n        catch (e)\n        {\n            // error handling\n            return false;\n        }\n\n        /*\n\n         return something it\'s a good practice if you want to chain Promises\n           |\n           |\n           V                                                                       */  \n        return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri)\n        .then(\n          function success(file){\n            return uploader.createUpload(serverUrl, file);\n          },\n          function failure(error){\n            return WinJS.Promise.wrapError(\'file not found\');\n  //                                        |_____________|  \n  // your are rejecting your promise with ---------^\n          }\n        ).then(\n          function (uploadOperation){\n\n  // Just avoid this type of code construction\n  // and add brace !\n  // adding brace augment readability and prevent errors !\n\n           // where do you set this ??? currentUpload = \'Canceled\'\n           // is part of winjs ???\n           if (currentUpload == \'Canceled\') \n\n           // why not handle your rejected promise ?\n           // by something like :\n           //if( uploadOperation == \'file not found\' )\n                return WinJS.Promise.wrapError(\'upload canceled\');\n            else\n                return ( currentUpload = uploadOperation.startAsync() );\n          }\n        ).then(\n// Promise resolve handler\n          function success(success){\n            currentUpload = false;\n            // success handling\n            return true;\n          } , \n// Promise reject handler\n          function failure(error){\n            currentUpload = false;\n            // error handling\n            return false;\n          }\n/*        ^  \n          |\nYOU HAVE HERE A DOUBLE CLOSING BRACE }} ???\n \xc2\xb0\n |  WHAT IS THIS PART FOR ??????\n |\n +------+---- Ending uploadFile with successive closing brace !\n        |\n        |+---------------- Declaration separator\n        ||      +--- New function declaration\n        ||      |\n        VV      V                     */\n        }, function pending(status){\n            var progress = status.progress,\n                percent = Math.round(progress.bytesSent / progress.totalBytesToSend * 100);\n            // progress handling\n        });\n        }\n\n/*\nALL THAT PART ABOVE IS NOT IN THE PROMISE CHAIN \nAND SHOULD BREAK YOUR CODE !!!\nHOW HAVE YOU EVER COULD RUN THIS ???\n*/\n
Run Code Online (Sandbox Code Playgroud)\n\n

也许它会错过您代码的一部分以确保这一点,因为在这种状态下您的代码必须中断!

\n\n
\n\n

也许调整可以是:

\n\n
var currentUpload;  // global\n\nfunction uploadFile(localFullPath, headers, serverUrl)\n{\n  var fileUri = new Windows.Foundation.Uri(\'ms-appdata:///local\' + localFullPath),\n      uploader = false;\n\n  try\n  {\n    uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();\n    uploader.method = \'PUT\';\n\n    // set headers to uploader\n    for (var key in headers)\n    {\n      if (headers.hasOwnProperty(key))\n        uploader.setRequestHeader(key, headers[key]);\n    }\n  }\n  catch (e)\n  {\n    // error handling\n    return false;\n  }\n\n  /*\n\n  return something it\'s a good practice if you want to chain Promises\n    |\n    |\n    V                                                                     */  \n  return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri)\n  .then(\n    function success(file){\n      return uploader.createUpload(serverUrl, file);\n    },\n    function failure(error){\n      return WinJS.Promise.wrapError(\'file not found\');// O|--------+\n    }//                                                             |\n  ).then(//                                                         |\n    function (uploadOperation){//  O|-------------------------------|\n      //                                                            |\n      // Just avoid this type of code construction                  |\n      // and add brace !                                            |\n      // adding brace augment readability and prevent errors !      |\n      //                                                            |   \n      // EDIT                                                       |\n      //if (currentUpload == \'Canceled\') { // <--- add brace        |\n      if (uploadOperation == \'file not found\') { //<---add brace <--+ \n\n        return WinJS.Promise.wrapError(\'upload canceled\');\n\n      } else { // <---- add braces\n\n        // even if it is valid\n        // avoid assignement like that\n        // so subtil to read / understand / debug ...\n        // return ( currentUpload = uploadOperation.startAsync() );\n\n        currentUpload = uploadOperation.startAsync();\n        // maybe debug here ?\n        console.log(\'currentUpload : \' + currentUpload );\n        return currentUpload;\n\n      } // <---- add brace\n    }\n  ).then(\n    function success(success){\n      currentUpload = false;\n      // success handling\n      return true;\n    } , \n    function failure(error){\n      currentUpload = false;\n      // error handling\n      return false;\n    } ,\n    function pending(status){\n      var progress = status.progress,\n          percent = Math.round(progress.bytesSent / progress.totalBytesToSend * 100);\n      // progress handling\n    }\n  ).done( // it is always a good thing to have a final catcher !!\n    function(){\n      // things are ok !\n      console.log(\'ok\');\n    },\n    function(err){\n      // make something with your error better than\n      alert(err);\n      console.log(\'ko\');\n\n    }\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑

\n\n

进一步看(我不使用winjs),有一些事情需要澄清:

\n\n
.then(\n  function success(file) {\n    return uploader.createUpload(serverUrl, file);\n  },\n  function failure(error) {\n    return WinJS.Promise.wrapError(\'file not found\');\n\n  }\n).then(\n  function(uploadOperation) {\n\n    if (currentUpload == \'Canceled\')\n      return WinJS.Promise.wrapError(\'upload canceled\');\n    else\n      return (currentUpload = uploadOperation.startAsync());\n  }\n).\n
Run Code Online (Sandbox Code Playgroud)\n\n

你在哪里设置这个:
\n currentUpload = \'Canceled\'
\n你正在检查,但我很确定这部分代码永远不会到达。
\n在你拒绝你的承诺之前:
\n return WinJS.Promise.wrapError(\'file not found\');
\n也许下一个then应该处理类似的事情:

\n\n
.then(\n  function success(file) {\n    return uploader.createUpload(serverUrl, file);\n  },\n  function failure(error) {\n    return WinJS.Promise.wrapError(\'file not found\');\n\n  }\n).then(\n  function(uploadOperation) {\n\n    if (uploadOperation == \'file not found\')\n      return WinJS.Promise.wrapError(\'upload canceled\');\n    else\n      return (currentUpload = uploadOperation.startAsync());\n  }\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望这能帮到您。

\n