2017-06-28 78 views
0

我對整個諾言有點新,所以我可能會做一些非常錯誤的事情。如果有人能夠啓發我,歡迎所有的建議/信息。Promise.all然後(js)

所以這裏是什麼,我試圖完成(簡體字,是絕對不適合用來理解的目的)代碼:

// Get data from webservice  
$scope.sendGet(id, option).then(function (response){ 
     // Fill the model 
     $scope.model[option] = response.data; 
    }).then(function(){ 
     if(option == $scope.PROFILES){ 

       var p1 = new Promise((resolve, reject) => { 
        $scope.getX1($scope.model[option][0][0].id); 
       }); 
       var p2 = new Promise((resolve, reject) => { 
        $scope.getX2($scope.model[option][0][0].id); 
       }); 
       var p3 = new Promise((resolve, reject) => { 
        $scope.getX3($scope.model[option][0][0].id); 
       }); 
       var p4 = new Promise((resolve, reject) => { 
        $scope.my_data = JSON.parse($scope.model[option][0][0].list); 
       }); 
      // Execute all promises to get the data 
      Promise.all([p1,p2,p3,p4]).then(() => { 
       debugger; 
       // Do some validation and extra formatting on the data we just downloaded 
       $scope.update(); 
      }); 
     } 
    }).then(function(){ 
     // Display the data to the user 
     $scope.move(option, 1, $scope.EDITING); 
    }); 

這裏預期的行爲是:

獲取數據 - >使用這個數據,使用ID從4個來源獲取數據(4個承諾) - >一旦所有的數據下載,更新一些引用,並做一些清洗 - >移動(這是一種方法,更新視圖和做一些其他的東西UI相關)

但是由於某些原因, debugger;$scope.update();從未得到執行。我嘗試將它們移動到與$scope.move()函數相同的位置,但它在Promise.all的數據已被檢索之前執行。

+3

您P1-P4的承諾永遠不會結束,因爲你既不叫'決心()'或'拒絕() '在其中任何一個 –

+0

你永遠不會解決你的承諾,因此他們爲什麼永遠不會執行'Promise.all'的「完成」回調。你的每一個承諾('p1-p4')都應該有一個'resolve(value)'或'reject(value)'。 – mhodges

+0

雖然,我應該指出,因爲您使用的是angularjs,所以您應該使用['$ q service'](https://docs.angularjs.org/api/ng/service/$q)。這是完全相同的語法,基本上只需用「$ q」替換「Promise」一詞並刪除'new'關鍵字。 – mhodges

回答

1

您永遠不會解決承諾1-4,因此Promise.all(...).then的「成功回調」從不會觸發。在給予每個承諾的構造函數的回調函數時,請撥打resolve,每個承諾的數據都會得到。

// ... 
var p1 = new Promise((resolve, reject) => { 
    resolve($scope.getX1($scope.model[option][0][0].id)); 
}); 
// ... 

這就是你如何從承諾「返回」數據,可以這麼說。詳情請參閱this article

編輯:如果$scope.getX1自身返回一個承諾,你可以簡單地把它分配給p1,即:

var p1 = $scope.getX1($scope.model[option][0][0].id); 
+2

我認爲'$ scope.getX1'返回'$ http'的承諾是安全的。所以你應該真正鏈接'.then()'離開getX1',並將解析/拒絕放入'$ http'回調中。否則,您正在解析承諾對象,而不是承諾返回的數據,並且它不會幫助OP。 – mhodges

+0

你說得很好。我添加了一個編輯來處理這種可能性。 – Will

+0

放棄「如果它返回承諾」。當它不包含時,將值包裝在'Promise.resolve'中也無濟於事。 – Bergi