2017-08-09 52 views
0

我有一個需要使用不同值進行克隆的對象數組。如何在for循環後返回單個promise,其中循環內數組的每個元素都執行多個異步調用

在準備主要修改的對象數組後,我會從每個承諾中獲得這些值,我將不得不保存這些值。所以我很多人需要這個作爲一個單一的承諾。

我不知道該怎麼做。

下面是我們需要克隆oldUser數據的示例。說老用戶的信用評分= 100;但對於新用戶,默認信用將由系統隨機創建。

對於用戶陣列中的每個用戶,很少的細節必須使用異步調用進行更新。 這是要求

function getUserCreditScore(user){ 
    var url = '/someurl'; 
    return $http.get(url).then(function(res){ 
    user.creditScore = (res.data) ? res.data : 0; 
    }); 
} 

function getUserRecomandations(user){ 
    var url = '/someurl'; 
    return $http.get(url).then(function(res){ 
    user.recommendation = (res.data) ? res.data : 'basic recommendation'; 
    }); 
} 

function getUserHelpInfo(user){ 
    var url = '/someurl'; 
    return $http.get(url).then(function(res){ 
    user.helpInfo = (res.data) ? res.data : 'Help Info'; 
    }); 
} 


function clone(){ 
    var newUsers = angular.copy(oldUsers); 

    for (var i=0; i<newUsers.length; i++){ 
    newUsers[i].id = undefined; 
    getUserCreditScore(newUsers[i]); 
    getUserRecommendation(newUsers[i]); 
    getUserHelpInfo(newUsers[i]); 
    } 

    var promises = _.map(newUsers, user => user.save()); 
    $q.all(promises).then(function (data) { 
    console.log(data); 
    } 
} 
+1

你需要等待通過'getCreditScore返回的承諾(newusers使用[1]);'...還有,你的'功能getCreditScore(用戶){'從來沒有使用用戶的說法?所以很難知道你正在嘗試做什麼 –

+0

我的不好getCreditScore看起來像下面 函數getCreditScore(用戶){ var url ='/ someurl'; 返回$ http.get(url).then(function(res){user.creditScore =(res.data)?res.data:0; }); } – user3741852

回答

0

你需要Promise.all承諾的陣列由getScreditScore

function getCreditScore(){ 
    var url = '/someurl'; 
    return $http.get(url).then(res => (res && res.data) ? res.data : res); 
} 

function clone(){ 
    var newUsers = angular.copy(oldUsers); 

    Promise.all(
     newUsers.map(newUser => { 
      newUser.id = undefined; 
      return getCreditScore() 
      .then(result => newUser.creditScore = result); 
     }) 
    ).then(results => // results will be an array of values returned by the get in getCreditScore(newUser) 
     Promise.all(newUsers.map(user => user.save())) 
    ).then(data => 
     console.log(data); // this will be the result of all the user.save 
    ); 
} 

注意返回上:在newUser.creditScore設置在然後在newUsers.map回調 - (對我原來的答案的最小改變)

Alternati vely,傳遞用戶getCreditScore

function getCreditScore(user){ 
    var url = '/someurl'; 
    return $http.get(url) 
    .then(res => (res && res.data) ? res.data : res) 
    .then(score => user.creditScore = score); 
} 

function clone(){ 
    var newUsers = angular.copy(oldUsers); 

    Promise.all(
     newUsers.map(newUser => { 
      newUser.id = undefined; 
      return getCreditScore(newUser); 
     }) 
    ).then(results => // results will be an array of values returned by the get in getCreditScore(newUser) 
     Promise.all(newUsers.map(user => user.save())) 
    ).then(data => 
     console.log(data); // this will be the result of all the user.save 
    ); 
} 

就個人而言,我會寫代碼

function getCreditScore(){ 
    var url = '/someurl'; 
    return $http.get(url).then(res => (res && res.data) ? res.data : res); 
} 

function clone(){ 
    var newUsers = angular.copy(oldUsers); 

    Promise.all(
     newUsers.map(newUser => { 
      newUser.id = undefined; 
      return getCreditScore() 
      .then(result => newUser.creditScore = result) 
      .then(() => newUser.save()) 
      .then(() => newUser); 
     }) 
    ).then(data => 
     console.log(data); // this will be the newUsers Array 
    ); 
} 

這是假設,雖然,你並不需要等待所有的$ HTTP .get在運行user.save()之前 - 事實上,由於newUser.save$http.get將會一前一後運行,因此可能會有一點(很少)更高性能

+0

非常感謝Jaromanda X.但我無法返回getCreditScore(newUser);因爲我需要兩個更多的承諾值才能在最終保存之前更新到新用戶對象。我該怎麼做? – user3741852

+0

'我需要兩個更多的承諾值更新到新的用戶對象' - 我不明白你的問題是如何提及的 - 我認爲你不能使用我在代碼中顯示的答案你到現在爲止還沒有出現過,甚至沒有絲毫提及? –

+0

對不起,我的問題很糟糕。我在摘要中沒有提到它,但我在問題(標題)中提到了它。 – user3741852

0

好的,我知道你的意思,你希望你的數組中的每一個元素做一些異步的事情。

所以你可以使用map和Promise.all。這裏是我的代碼:

const asyncFunction = (item, cb) => { 
    setTimeout(() => { 
    console.log(`done with ${item}`); 
    cb(); 
    }, 1000); 
} 

let requests = [1, 2, 3].map((item) => { 
    return new Promise((resolve) =>{ 
    asyncFunction(item, resolve); 
    }); 
}); 

Promise.all(requests).then(() => console.log('done')); 
+0

謝謝yzfdjzwl。我會試一試。 – user3741852

相關問題