簡體   English   中英

Angular JS承諾鏈接

[英]Angular js promises chaining

我一直在努力尋找過去兩天的承諾,到目前為止,我已經做到了。 任何引導性的方向都很好,因為我認為我感到困惑。

因此這是我的服務,必須在圖像捕獲后按超時順序運行,以便服務器進行更新:

returnImage: function() {
      var results = {};
   function getCameraDirectory(){
     // Get directory infomation from camera
     var list = [];
     deferred = $q.defer();
     console.log("getCameraDirectory");
     $http.get(BASE_URL + IMAGE_URL).then(
     function(response){
       $("<div>").html(response.data).find('a').each(function() {
         var text = $(this).text();
         if(text !== 'Remove'){
         list.push(text);
       }
       });
        if(results.hasOwnProperty("medialist")){
          results["filelist"] = list.diff(results["medialist"]);
        }else{
          results["medialist"] = list;
        }
        deferred.resolve('getCameraDirectory')
     },
     function(error){
       console.log(error);
        deferred.reject(error);
     });
   }

   function setCameraMode(){
     // sets the camera mode to picture, multi-image, video
     deferred = $q.defer();
     console.log("setCameraMode")
     $http.get(BASE_URL + '?custom=1&cmd=3001&par=0').then(
     function(response){
       if(response.status === 200){
        results["mode"] = 'image';
       deferred.resolve('setCameraMode');
     }else{
       deferred.reject("Counldnt change Camera mode");
     }
     },
     function(error){
       console.log(error);
        deferred.reject(error);
     });
   }

   function captureMedia(){
     // starts the capture process picture, multi-image, video
     console.log("captureMedia")
      deferred = $q.defer();
     $http.get(BASE_URL + '?custom=1&cmd=1001').then(
     function(response){
       if(response.status === 200){
        results["date"] = Date.now();
       deferred.resolve('captureMedia');
     }else{
       deferred.reject("Counldnt insiate image capture");
     }
     },
     function(error){
       console.log("error");
        deferred.reject(error);
     });
   }

   function saveMedia(){
     console.log('saveMedia');
     deferred = $q.defer();
     console.log(results["filelist"]);
     var mediaName = results["filelist"];
     var url = BASE_URL + IMAGE_URL + mediaName;
     var targetPath = cordova.file.externalRootDirectory + 'photoboothinabox/' + mediaName;
     var filename = targetPath.split("/").pop();
     $cordovaFileTransfer.download(url, targetPath, {}, true).then(function (response) {
         deferred.resolve('saveMedia');
         console.log('Success');
     }, function (error) {
         deferred.reject("Counldnt save to disk");
         console.log('Error');
     }, function (progress) {
         // PROGRESS HANDLING GOES HERE
         console.log(progress)
     });
   }
   function test(){
     console.log("past it")
   }

    var deferred= $q.defer(),
    promise = deferred.promise;

      promise.then(getCameraDirectory())
            .then(setCameraMode())
            .then(captureMedia())
            .then(getCameraDirectory())
            .then(saveMedia());
  return promise;

},

它隨處可見...

PS I工作建築為生

首先,@ sjokkogutten的答案是解決之道。 將您的業務邏輯放在盡可能高的位置(例如在服務中)使該應用程序更具可維護性和可測試性。

請不要使用$http.get(...).then(onSuccess, onError)的第二個參數,因為它不可鏈接。

$http.get(...).then(onSuccess).except(onError)是更好的模式。

關於承諾的幾點說明

當你鏈接的承諾,每個then回調,輸入前一個承諾。

$http.get(...)
  .then(function (result) {
    return 'getCameraDirectory'; // Or $q.resolve('getCameraDirective'), doesn't matter
  })
  .then(function (result2) {
    // result2 is 'getCameraDirectory'
  });

在兌現承諾時, 務必退貨! 忘記一次回報很容易,您的承諾鏈最終將解決為undefined

您的示例鏈接了一些方法,但是這些方法不返回任何內容。 這意味着下一個鏈接的回調不接收參數。 最后, saveMedia()不返回任何內容,因此整個promise鏈都解析為undefined

請注意,整個示例中只有一個return語句。

拒絕

假設您要在一個回調中根據條件斷開鏈。

您需要拒絕承諾。 then不再調用所有直接鏈接的s。

$http.get(...)
  .then(function (result) {
    if (result.length > 0) {
      return result;
    } else {
      return $q.reject('result is empty'); // or throwing error
    }
  })
  .then(function (result2) {
    // result2 is non empty!
  })
  .catch(function (message) {
    // this callback is called when result is empty OR when the $http.get call rejects (eg. returns 404)
    // Return something if you want to chain further
    return 'Back on track';
  })
    .then(function (result3) {
      // result3 === 'Back on track'
      // This callback is only called when coming from `except`
    })
    .catch(function (message2) {
      // This callback is called when previous 'except' or 'then' is rejecting
    });

$http已經返回了諾言,因此在調用服務時無需使用$q.defer() 相反,我建議將所有$http請求放在單獨的服務/服務中:

app.factory('DataService', function($http, $cordovaFileTransfer) {
  var getCameraDirectory = function() {
    return $http.json("/api/...") // returns a promise
  };

 var setCameraMode= function() {
    return $http.json("/api/...") 
  };

 var getCameraDirectory = function() {
    return $http.json("/api/...") 
  };

 var captureMedia = function() {
    return $http.json("/api/...") 
  };

 var saveMedia = function() {
    return  $cordovaFileTransfer.download(url, targetPath, options, trustHosts) // I am not sure, but I am assuming that $cordovaFileTransfer.download() is returning a promise. 
  };

  return {
    getCameraDirectory: getCameraDirectory,
    setCameraMode: setCameraMode,
    captureMedia: captureMedia,
    saveMedia: saveMedia
  }
});

在你的控制器,你可以使用現在解決您的承諾then

myApp.controller('MyController', function ($scope, DataService) {     
    DataService.getCameraDirectory().then(
      function(){ //resolve getCameraDirectory 
        // getCameraDirectory successcallback
      },
      function(){
        // getCameraDirectory errorcallback
      }).then( // resolve setCameraMode 
        function(){
          // setCameraMode successcallback
        },
        function(){
          // setCameraMode errorcallback
        }).then( // resolve captureMedia 
          function(){
            // captureMedia successcallback
          },
          function(){
            // captureMedia errorcallback
          }).then(// resolve saveMedia
            function(){
              // saveMedia successcallback
            },
            function(){
              // saveMedia errorcallback
            })   
});

請注意,我實際上尚未實現上述代碼,但應該為您提供一個概述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM