我需要建立map_of_uuid_ids_and_field_names_to_an_array_of_field_values
。
我需要在循环完成循环后返回此对象。怎么样?
现在我的代码挂起在这个循环的内部。我看着它,意识到内部“then()”语句中没有“return”语句。但是当我需要循环代码时,我怎么能在那里放一个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;
});
}
答案 0 :(得分:1)
首先,您不能直接从使用异步操作获取结果的函数返回结果。您可以返回一个承诺(解决后)将使结果可用。
其次,无论何时你想调用一个在循环中返回promise的异步操作,你想知道循环中所有异步操作何时完成,通常的技术是在数组中累积promises并使用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
});