2017-07-31 26 views
-2

我需要建立map_of_uuid_ids_and_field_names_to_an_array_of_field_values如何從NodeJS的循環中返回Promise?

我需要在循環完成循環後返回此對象。怎麼樣?

現在我的代碼掛在這個循環的內部。我看着它,意識到內部的「then()」語句沒有「return」語句。但是,當我需要代碼循環時,我該如何在那裏放置返回語句?我如何從這個內部循環返回一個Promise?

function get_map_of_uuid_ids_and_field_names_to_an_array_of_field_values(string_from_api_call, api_key_whose_name_should_match_the_name_of_a_database_field) { 

    return new Promise(function(resolve, reject){ 

     var map_of_uuid_ids_and_field_names_to_an_array_of_field_values = {}; 
     sanitized_string_from_api_call = database_queries.sanitize_string(string_from_api_call); 


     // 2017-07-10 -- this fixes: 
     // TypeError: Cannot read property 'split' of null, at get_map_of_uuid_ids_and_field_names_to_an_array_of_field_values (/home/ec2-user/daemons/deduplication_api/v9/dupe-res/actions.js:456:82) 
     if (sanitized_string_from_api_call) { 

      var array_of_words_from_string_from_api_call = sanitized_string_from_api_call.split(/\s+/); 

      for (var k in array_of_words_from_string_from_api_call) { 
       var word = array_of_words_from_string_from_api_call[k]; 

       // 2017-02-27 -- for the sake of performance, we skip over any string of 2 letters or less. 
       // This means headquarters_country_code and headquarters_state_code need special handling. 
       if (word.length > 2) { 

        return database_queries.get_map_of_type_of_profile_and_profile_id_pointing_to_document(word) 
         .then(function(map_of_type_of_profile_and_profile_id_pointing_to_document) { 

          if (map_of_type_of_profile_and_profile_id_pointing_to_document) { 

           map_of_uuid_ids_and_field_names_to_an_array_of_field_values = merge_objects(map_of_uuid_ids_and_field_names_to_an_array_of_field_values, transform_map_of_profile_type_and_profile_id_to_map_of_uuid_to_documents(map_of_type_of_profile_and_profile_id_pointing_to_document)); 

          } 
         }); 
       } 
      } 

     } else { 
      console.log("the string value was null when api_key_whose_name_should_match_the_name_of_a_database_field was : " + api_key_whose_name_should_match_the_name_of_a_database_field); 
     } 

     return map_of_uuid_ids_and_field_names_to_an_array_of_field_values; 
    }); 
} 
+4

準確的長名字是什麼?! – Vandesh

+0

如果它是異步的,你不能真正返回。 –

+0

這是一個有趣的問題:) –

回答

1

首先,您不能直接從使用異步操作獲取結果的函數返回結果。您可以返回(解決時)將使結果可用的承諾。第二,任何時候你想調用一些在循環中返回promise的異步操作,並且想要知道何時在循環中啓動了所有異步操作,通常的技巧是將promise保存在一個數組中,使用Promise.all()告訴你他們什麼時候全部完成。

第三,你的超長變量名使你的代碼難以閱讀。我不知道你是否只是爲了你的問題而這樣做,或者你是否通常以這種方式進行編碼,但是我發現這些名字太長以致於模糊了流程和代碼的閱讀。我贊成有意義的變量名稱,但是這樣做的結果是它破壞了代碼的可讀性,我無法想象必須輸入所有這些才能處理代碼。

因此,使變量名稱更具可讀性(對我來說)和應用上述技術後,這裏是你的代碼的簡化版本:

function get_idMap(str, apiKey) { 
    let promises = []; 
    let idMap = {}; 
    let santizedString = database_queries.sanitize_string(str); 
    if (santizedString) { 
     santizedString.split(/\s+/).forEach(function(word) { 
     // 2017-02-27 -- for the sake of performance, we skip over any string of 2 letters or less. 
     // This means headquarters_country_code and headquarters_state_code need special handling. 
     if (word.length > 2) { 
      promises.push(database_queries.get_profileMap(word).then(function(profileMap) { 
       if (profileMap) { 
        idMap = merge_objects(idMap, transformProfile(profileMap)); 
       } 
      })); 
     }); 
    } else { 
     console.log("the string value was null when apiKey was : " + apiKey); 
    } 
    return Promise.all(promises).then(function() { 
     return idMap; 
    }); 
} 

而且,因爲這會返回一個承諾,你會使用它像這樣:

get_idMap(someStr, yourKey).then(function(idMap) { 
    // use the idMap here 
}).catch(function(err) { 
    // handle error here 
}); 
+1

爲什麼downvote?這是不是教導如何解決OP代碼中的問題類型?如果你提供downvote反饋,也許我可以改善答案。 – jfriend00

+2

您的變量名稱可能不夠長。

+0

說真的。爲什麼多重降價?這個答案有什麼問題? – jfriend00