大家好!今天让小编来大家介绍下关于js的yield(JS单线程 如何避免阻塞)的问题,以下是小编对此问题的归纳整理,让我们一起来看看吧。
文章目录列表:
前者当对应的notify()被调用或者超出指定时间时线程重新进入可执行状态,使得线程在指定的时间内进入阻塞状态,保证任务队列和异步任务里的信号量是同一个,JS单线程避免阻塞方法: 1.sleep()方法:sleep()允许指定以毫秒为单位的一段时间作为参数,本文目录JS单线程 如何避免阻塞js 循环中循环变量i=0,步伐不为1的时候,i加不上去,一直是0!!iOS类似async/await的用法JS单线程 如何避免阻塞 阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),然后执行多个任务的主队列使用信号量进行中断,执行wait(Forever)就会中断当前线程),同时返回下一个yield后面数据。
本文目录
JS单线程 如何避免阻塞
阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),JS单线程避免阻塞方法: 1.sleep()方法:sleep()允许指定以毫秒为单位的一段时间作为参数,使得线程在指定的时间内进入阻塞状态,不能得到CPU时间,指定的时间一过,线程重新进入可执行状态。 典型地,sleep()被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。 2.suspend()和resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。 suspend()和resume()被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用resume()使其恢复。 3.yield()方法:yield()使得线程放弃当前分得的CPU时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得CPU时间。调用yield()的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。 4.wait()和notify()方法:两个方法配套使用,wait()使得线程进入阻塞状态,有两种形式,一种允许指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的notify()被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的notify()被调用。
js 循环中循环变量i=0,步伐不为1的时候,i加不上去,一直是0!!
for(var i=0;i《10;i+2){//会编译失败!不能+2;i自身不会增加2的yield sum+=i;}可以修改为for(var i=0;i《10;i++){yield sum+=i+2;//每次+2;}
iOS类似async/await的用法
总结:yield修饰符具有中断性,将yield后面的数据返回,同时具有恢复现场的特性,再次进入可以携带数据,同时返回下一个yield后面数据,当迭代完毕,返回一个value为空的数据。done被置为true.
那么利用这个特性,可以实现异步流程同步化。 思路:迭代器的next我们可以理解为一次请求,我们在当前请求的回调里实现迭代器的下一个next,这样异步流程就能实现顺序执行。
1 .首先我们一个参数是回调的方法,这样在异步耗时操作之后可以调用这个回调,进而进行下一次的next调用。**
2 .然后我们需要把多个异步请求的流程写下来(其实就是生成器),比如1,2,3,4四个请求顺序执行,
3. 有了生成器步骤,那么接下来我们就可以用迭代器next来实现顺序执行:
4. 调用:
直接上源码:
可以看出 四个模拟的网络请求请求时间不同,但是执行顺序按照了我们规定的顺序执行。
至于后面我们常用的async/await用法其实跟这个差不多。只不过是经过了一层包装,让外部行为看起来比较统一。经过async修饰过方法会被包装成promise对象,这跟我们的上面的 mockReq 其实大同小异,然后再网络请求的回调里执行resolve/ reject(其实就是上面的callBack).当然promise功能还有很多,我们只是讨论模仿async/await相关问题。
经过上面的描述,我们已经知道js的协程相关特性,但是iOS没有协程相关的方法,没有yield,没有async /await.我们想一下,yield主要作用是什么呢? 中断 + 恢复 现场的功能。虽然iOS没有这些,但是想一下GCD里面的信号量semaphore也具有中断特性(semaphore的数量为0,执行wait(Forever)就会中断当前线程),我们先开启一个异步任务,然后执行多个任务的主队列使用信号量进行中断,然后在单个的异步任务队列的回调里重新使信号量加一,从而恢复主任务队列,然后执行下一个子任务,依次类推。
那思路已经有了,其实就是把js里的yield换成了semaphore.涉及到任务队列,信号量,异步任务,我们可以用一个对象来关联他们,保证任务队列和异步任务里的信号量是同一个,但是对象在方法栈里生成,在方法栈结束时会被释放,这时异步任务可能还没有回来,此时就需要一个全局的dic来持有,通过barrier监听主任务队列,等到任务队列里的所有任务都执行完毕之后,将这个管理对象释放掉: talk is cheap,show me the code
用法
我们要使用分两步: 第一步:需要构造一个 JTWaitClosure 类型的block。如上面的的请求百度、必应。 第二步:在 JT_AsyncOperation 的async方法的block中,使用JT_AWAIT(’任务’)的形式,来实现类似async/await的用法。
使用JT_AsyncOperation 的async/await的优点:
需要注意的事情:因为主任务队列是异步并发,所以在更新UI相关的操作,需要切换到主线程。
以上就是小编对于js的yield(JS单线程 如何避免阻塞)问题和相关问题的解答了,js的yield(JS单线程 如何避免阻塞)的问题希望对你有用!