美文网首页
NSConditionLock解决回调顺序场景

NSConditionLock解决回调顺序场景

作者: 举个栗子wow | 来源:发表于2020-09-18 19:53 被阅读0次

NSConditionLock条件锁在开发中几乎很少用到,虽然知道他的作用但是之前并没有碰到一个用它解决问题的场景。
描述如下一个场景:三个异步任务在并发队列中,同时执行一个耗时任务X,当X执行完毕之后会回调一次数据,如何保证调用顺序和回调顺序一致?
eg:ABC三个异步任务依次书写,并发异步下假如实际调用顺序为BCA,希望回调顺序也是BCA,但其实可能A执行X时最先处理完,但不回调,等待BC回调过后再进行回调,即调用顺序为BCA,回调顺序为BCA,且并发。

利用NSConditionLock可以比较方便实现这个效果,思路如下:通过一个容器记录方法的调用顺序,主动解锁第一个调用,第一个调用一次解锁剩下的调用。

前置一个问题,如果我先进行条件解锁,再进行同条件加锁,此处无效,像下面这样

self.conditionLock.unlock(withCondition: 4)
self.conditionLock.lock(whenCondition: 4)
print("aaa")

正文:
变量部分:

var methodIndex : Array<Int> = Array()  //标记调用顺序的容器
    var methodIndexLock : NSLock = NSLock.init() //给容器读写加锁的互斥锁
    var methodCurrnetLock : Int = 0 //当前解锁到的位置
    
    lazy var conditionLock : NSConditionLock = {
        return NSConditionLock.init(condition: 0)
    }() //条件锁
//并发调用三个异步任务,为了比较直观,我把第一个任务进行延迟
    func testConditionLock() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.5, execute: {
            print("第一个任务开始了")
            self.someMethod(1) {
                print("第一个任务返回了")
            }
        })
        DispatchQueue.global().async {
            print("第二个任务开始了")
            self.someMethod(2) {
                print("第二个任务返回了")
            }
        }
        DispatchQueue.global().async {
            print("第三个任务开始了")
            self.someMethod(3) {
                print("第三个任务返回了")
            }
        }
        
        //这里备注下:此处是希望解锁第一个加锁的,也就是像上面前置问题那样,使第一把条件锁无效
        DispatchQueue.main.asyncAfter(deadline: .now()+1) {
            self.conditionLock.unlock(withCondition: self.methodIndex[0])
        }
    }
//第一个参数只是一个标识,不代表调用顺序
func someMethod(_ actionIndex:Int,callback:()->Void) {
        //对容器读写加锁
        self.methodIndexLock.lock()
        self.methodIndex.append(actionIndex)
        self.methodIndexLock.unlock()
        
        let t = Double(arc4random() % 10)
        Thread.sleep(forTimeInterval: t) //此处进行休眠,模拟耗时操作
        print(actionIndex,t)
        self.conditionLock.lock(whenCondition: actionIndex)
        callback()
        self.methodCurrnetLock += 1
        guard self.methodIndex.count > self.methodCurrnetLock else {
            return
        }
        self.conditionLock.unlock(withCondition: self.methodIndex[self.methodCurrnetLock])
        print(self.methodCurrnetLock,self.methodIndex)
        
    }

相关文章

  • NSConditionLock解决回调顺序场景

    NSConditionLock条件锁在开发中几乎很少用到,虽然知道他的作用但是之前并没有碰到一个用它解决问题的场景...

  • 回调--CallBack

    回调是一个编程技巧,用于解决顺序流程无法解决或者说使用顺序流程来解决会十分麻烦的问题 比如: 场景一:在打游戏的时...

  • day05-ES6中的Promise-API&&

    回调地狱(callback-hell): 此程序不能保证执行的先后顺序: 解决方式(嵌套): 解决回调地狱(Pro...

  • nodejs--day4笔记

    1. 同步与异步API 回调函数 通过回调函数返回异步API的值 代码执行顺序 2. promise 解决回调...

  • 异步编程之Promise(三)

    promise可以解决回调函数带来的问题 1、解决回调地狱 案例场景:在文档a.txt中存放正文档b.txt的路径...

  • Android-->Behavior上手入门

    开始布局时,方法回调顺序: 开始滚动子View时, 方法回调顺序 源码地址:https://github.com/...

  • uiscrollview 回调顺序

    执行顺序:willBeginDraggingDidScrollwillEndDraggingDidEndDragg...

  • promise

    异步的出现,解救了无数深陷 回调 不能自拔的人们。 1.回调地狱 过深的嵌套,导致回调地狱,难以追踪回调的执行顺序...

  • JavaScript 异步操作里的嵌套回调函数

    嵌套回调函数经常用在两个逻辑上具有先后顺序的异步操作场景中。 思考下面的问题:我们如何按顺序加载两个脚本? 自然的...

  • ES6快速学习(七)Promise

    回调函数 Promise 解决了什么痛点 回调地狱 代码如下 我的第一个Promise使用 解决回调地狱之链式...

网友评论

      本文标题:NSConditionLock解决回调顺序场景

      本文链接:https://www.haomeiwen.com/subject/qytsyktx.html