0

情况如下:

有超过 3 个异步任务。每一项只能在前一项完成后才能执行。是的,必须在上一个完成之后。这就是为什么调度组可能不适合这种情况,因为它不太关心“排序”。我正在寻找的是一种无需太多嵌套即可编写此类代码的好方法 - 就像'promisekit'打破嵌套块所做的那样。

我还看到一些人建议使用“串行队列”。好吧,我尝试使用下面的代码:

- (void) asyncMethod1WithCompletion: (void(^)())completion
{
    int64_t delayInSeconds = 5.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"async 1 finished");
        completion();
    });
}

- (void) asyncMethod2WithCompletion: (void(^)())completion
{
    int64_t delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"async 2 finished");
        completion();
    });
}

我使用串行队列调用这些方法:

dispatch_queue_t serialQueue = dispatch_queue_create("testqueue", DISPATCH_QUEUE_SERIAL);

dispatch_sync(serialQueue, ^{
    NSLog(@"async1 started");
   [self asyncMethod1WithCompletion:^{

   }];
});

dispatch_sync(serialQueue, ^{
    NSLog(@"async2 started");
    [self asyncMethod2WithCompletion:^{

    }];
});

如果一切正常,异步任务 2 应该在 5 秒后开始执行,这是异步任务 1 的完成时间

然而,结果并不如我所料:

2016-09-14 18:59:39.853 SerialQueueTest[32002:2292385] async1 开始

2016-09-14 18:59:39.854 SerialQueueTest[32002:2292385] async2 开始

2016-09-14 18:59:41.854 SerialQueueTest[32002:2292385] 异步 2 完成

2016-09-14 18:59:45.353 SerialQueueTest[32002:2292385] 异步 1 完成

我写错代码了吗?有没有编写较少嵌套代码的本机方式?如果有 5-6 个异步任务,并且每个任务都依赖于彼此的结果,那么代码将非常庞大。我什至会想到一个案例:一个通用的登录功能,它还集成了一些第三方帐户登录。

我也在考虑以不同的方式使用调度组:1.进入组并完成第一个异步任务并退出组。2.在dispatch_group_notify块内,再次进入第二个异步任务的调度组。3. 在 disptach_group_notify 块外,调用第二个异步任务并再次退出组。4.编写第二个dispatch_group_notify,用于通知第二个任务完成。

4

2 回答 2

0
- (dispatch_group_t) asyncMethod1
{
    NSLog(@"async1 started");
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    int64_t delayInSeconds = 5.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"async 1 finished");
        dispatch_group_leave(group);
    });
    return group;
}

- (dispatch_group_t) asyncMethod2
{
    NSLog(@"async2 started");
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    int64_t delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        NSLog(@"async 2 finished");
        dispatch_group_leave(group);
    });
    return group;
}

并使用:

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

dispatch_async(queue, ^{
   dispatch_group_notify([self asyncMethod1], queue, ^{
      [self asyncMethod2];
   });
});

dispatch_group_t那里看起来很像promise。如您所见,您甚至可以使用并发队列。

于 2016-09-14T14:15:29.127 回答
0

您可以在此处使用 NSOperationQueue。

  1. 创建n 个块操作(NSBlockOperation),其中n是您拥有的异步操作的数量。
  2. 按照您希望它们执行的顺序将它们添加到 NSOperationQueue 中。
  3. 将 NSOperationQueue 的 maxConcurrentOperationCount 设置为 1 以使队列为串行。
于 2016-09-14T22:11:58.590 回答