【发布时间】:2016-04-24 14:51:06
【问题描述】:
我在 iOS 应用中有一个函数,它使用dispatch_group 对多个休息请求进行分组:
static func fetchCommentsAndTheirReplies(articleId: String, failure: ((NSError)->Void)?, success: (comments: [[String: AnyObject]], replies: [[[String: AnyObject]]], userIds: Set<String>)->Void) {
var retComments = [[String: AnyObject]]()
var retReplies = [[[String: AnyObject]]]()
var retUserIds = Set<String>()
let queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
Alamofire.request(.GET, API.baseUrl + API.article.listCreateComment, parameters: [API.article.articleId: articleId]).responseJSON {
response in
dispatch_async(queue) {
guard let comments = response.result.value as? [[String: AnyObject]] else {
failure?(Helper.error())
return
}
print(comments)
retComments = comments
let group = dispatch_group_create()
for (commentIndex, comment) in comments.enumerate() {
guard let id = comment["_id"] as? String else {continue}
let relevantUserIds = helperParseRelaventUserIdsFromEntity(comment)
for userId in relevantUserIds {
retUserIds.insert(userId)
}
retReplies.append([[String: AnyObject]]())
dispatch_group_enter(group)
Alamofire.request(.GET, API.baseUrl + API.article.listCreateReply, parameters: [API.article.commentId: id]).responseJSON {
response in
dispatch_async(queue) {
if let replies = response.result.value as? [[String: AnyObject]] {
for (_, reply) in replies.enumerate() {
let relevantUserIds = helperParseRelaventUserIdsFromEntity(reply)
for userId in relevantUserIds {
retUserIds.insert(userId)
}
}
retReplies[commentIndex] = replies
}
dispatch_group_leave(group)
}
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
success(comments: retComments, replies: retReplies, userIds: retUserIds)
}
}
}
从我的代码中可以看出,我在同一个article 下获取所有comments,然后在每个comment 下获取对应的replies。完成所有请求后,我调用我的success 回调。这可以使用 GCD 的dispatch_group 来实现。
现在我正在将相同的功能迁移到 android。
public static void fetchCommentsAndTheirReplies(Context context, String articleId, final StringBuffer outErrorMessage, final Runnable failure, final ArrayList<JSONObject> outComments, final ArrayList<ArrayList<JSONObject>> outReplies, final HashSet<String> outUserIds, final Runnable success) {
final RequestQueue queue = Volley.newRequestQueue(context);
HashMap<String, String> commentParams = new HashMap<>();
commentParams.put(API.article.articleId, articleId);
JsonArrayRequest commentRequest = new JsonArrayRequest(Request.Method.GET, API.baseUrl + API.article.listCreateComment, new JSONObject(commentParams), new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length(); i++) {
JSONObject comment = response.getJSONObject(i);
outComments.add(comment);
outUserIds.addAll(helperParseRelaventUserIdsFromEntity(comment));
outReplies.add(new ArrayList<JSONObject>());
//TODO: DISPATCH_GROUP?
String id = comment.getString("_id");
HashMap<String, String> replyParams = new HashMap<>();
replyParams.put(API.article.commentId, id);
final int finalI = i;
JsonArrayRequest replyRequest = new JsonArrayRequest(Request.Method.GET, API.baseUrl + API.article.listCreateReply, new JSONObject(replyParams), new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
for (int j = 0; j < response.length(); j++) {
JSONObject reply = response.getJSONObject(j);
outUserIds.addAll(helperParseRelaventUserIdsFromEntity(reply));
outReplies.get(finalI).add(reply);
}
} catch (JSONException ex) {}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {}
});
queue.add(replyRequest);
}
success.run();
} catch (JSONException ex) {}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
outErrorMessage.append(error.getMessage());
failure.run();
}
});
queue.add(commentRequest);
}
请注意,我使用success 是在我获得所有comments 之后和获得所有replies 之前执行的。
那么我怎样才能对它们进行分组并延迟响应呢?
我正在研究毛茸茸的实现,比如
taskCount++;
if (taskCount == totalCount) {
success.run();
}
在回复块中,但是看起来很乏味。
【问题讨论】:
-
你看过
RxJava吗?这是它的预期用例。异步操作以及对结果和中间体的操作。 -
抱歉,您能否解释一下,您的 iOS 代码中发生了什么?为什么你首先要使用
dispatch_group?无论您是发送还是接收某些东西,只要只涉及单个服务器,不按顺序执行操作就没有多大帮助。而且移动连接肯定不会有任何好处,这通常会将并发网络请求的数量限制为 1。您最好在阻塞模式下,在单个后台请求中执行上述所有操作。
标签: java android ios swift android-asynctask