JS(AS)中的原子操作概述

原子操作这是Java多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

当然JS是单线程的,所以不存在线程打断这么一说,我只是从Java中借引了这么一个概念。如果一段JS代码在执行过程中没有未知操作被引入,那么这段代码就是100%可控和安全的,这就是原子操作。反之非原子操作可能会因为外界操作的引入导致代码变得难以控制而产生隐晦的bug。

下面举例说明非原子操作可能会带来的问题

function start()
{
    player = new Player();
    player.start();
    fireEvent('start');
    player.resume();
    fireEvent('play');
}

function stop()
{
    player.pause();
    fireEvent('pause');
    player.stop();
    player = null;
    fireEvent('stop');
}

这段代码中定义两个方法,start表示开始播放视频,里面分别有两段原子操作,在每个原子操作结束之后都向外发送了事件;stop方法类似。代码看起来简单而完美,但由于这两个方法都不是原子操作,所以可能会存在隐患。

返回栏目页:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/

下面我们用同样简单的方式使用这两个方法就会产生混乱的结果。

on('start', function(){
    stop();
});
start();

这段代码试图让播放器一开始播放就停止,意图明确。但是它却会让实际执行结果变成下面这样

player = new Player();
player.start();
fireEvent('start');
//监听start事件后引入的操作
player.pause();
fireEvent('pause');
player.stop();
player = null;
fireEvent('stop');
//end
player.resume();
fireEvent('play');

这段代码对外界来说居然在stop事件发生之后还会发生一次play事件,堪称诡异。

究其原因是因为触发play事件后引入外部操作导致下一个原子操作所依赖的前提改变。这就是我说的非原子操作的隐患。

那么如何避免这种问题呢,把代码改成这样就行

function start()
{

    if (!started)
    {
        player = new Player();
        player.start();
        started = true;
        fireEvent('start');
    }

    if (started && !played)
    {
        player.resume();
        played = true;
        fireEvent('play');
    }
}

function stop()
{

    if (started && played)
    {
        player.pause();
        played = false;
        fireEvent('pause');
    }

    if (started)
    {
        player.stop();
        player = null;
        started = false;
        fireEvent('stop');
    }
}

只需要给每个原子操作加上足够的前提判断就可以避免上述问题。

有时候我们无法避免非原子操作,但是我们要认清哪些是原子操作,不要想当然得认为上一个原子操作产生的结果必然会是下一个原子操作的环境。在每个原子操作前加上足够的判断。

作者:cnblogs 小夜 Clifford

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索player
, 代码
, start
, 原子
, stop()方法
, 原子操作
, stop
fireEvent
js 原子操作、操作系统概述、操作风险管理概述、计算机操作系统概述、swd协议操作概述,以便于您获取更多的相关知识。

时间: 2024-11-03 02:44:15

JS(AS)中的原子操作概述的相关文章

js 根目录:实用技巧:在JS应用中定义上下文根目录变量

在JavaWEB应用中,上下文是十分重要的概念,但在JavaScript中没有对应的概念,也不能通过解析URL得到,因此往往在使用第三方产品时,遇到不小的麻烦,我们可以用<%@page contentType="text/javascript" pageEncoding="utf-8"%>指令将jsp文件标识为js文件,在这个jsp文件中定义供js调用的上下文变量.这里以配置百度UEditor在线编辑器为例.一.文件路径1.UEditor路径:上下文/u

在JS文件中调用JS文件,可以不停的调用

js 今天本站的广告客户时代互连在本站做的全站漂浮广告,本来是本站已经预设置了一个JS的广告位,并且也有漂浮代码了!但是他们说漂浮的效果好象不好,让我换成他们的JS文件! 于是我开始搜索最终找到了在JS文件中调用其他的JS文件,并且把这种功能可以扩展下: 就是说在1.JS中调用2.JS,在2.JS中调用3.JS--    调用的方法和代码如下: 在1.js中输入下面代码可以调用2.js  document.write("<scr"+"ipt  language=java

在Node.js应用中读写Redis数据库的简单方法

  这篇文章主要介绍了在Node.js应用中读写Redis数据库的简单方法,Redis是一个内存式高速数据库,需要的朋友可以参考下 在开始本文之前请确保安装好 Redis 和 Node.js 以及 Node.js 的 Redis 扩展 -- node_redis 首先创建一个新文件夹并新建文本文件 app.js 文件内容如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var redis = require("redis") ,

在Node.js应用中使用Redis的方法简介

  在开始本文之前请确保安装好 Redis 和 Node.js 以及 Node.js 的 Redis 扩展 -- node_redis 首先创建一个新文件夹并新建文本文件 app.js 文件内容如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var redis = require("redis") , client = redis.createClient();   client.on("error", f

Node.js编程中客户端Session的使用详解

  这篇文章主要介绍了Node.js编程中客户端Session的使用详解,是Node.js入门学习中的基础知识,需要的朋友可以参考下 静态网站很容易扩展.你只需要全部缓存,不需要考虑从不同服务器组合有状态的内容给用户. 可惜,大多数Web应用使用有状态的内容提供个性化体验.如果你的应用可以登录,就需要记住用户的Session.经典的处理方法是客户端设置包含随机唯一Session标识的Cookie,被标识的Session数据保存到服务端. 扩展有状态服务 当扩展服务的时候,你肯定有三种选择: 不同

浅析Js(Jquery)中,字符串与JSON格式互相转换的示例

这几天,遇到了json格式在JS和Jquey的环境中,需要相互转换,在网上查了一下,大多为缺胳膊少腿,也许咱是菜鸟吧,终于测试成功后,还是给初学者们一个实例吧   首先,准备新建一个js文件.以下是JSON2.js的内容,把内容拷到js文件中,以便调用: 复制代码 代码如下: /*     http://www.JSON.org/json2.js     Public Domain.     NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RI

在js文件中如何获取basePath处理js路径问题

js路径的问题有时候不好处理,在jsp中,我们可以用el表达式直接获取basePath,但是在单独js文件中不能用el表达式,又不想在jsp中单独的写个变量,可以用以下方法: 复制代码 代码如下: var location = (window.location+'').split('/'); var basePath = location[0]+'//'+location[2]+'/'+location[3]; var url = basePath + '/js/xxx.js';

在JS方法中返回多个值的方法汇总

  本文给大家汇总了在javascript方法中返回多个值的方法,都是在个人项目中检验过的,这里推荐给大家,有需要的小伙伴可以参考下. 在使用JS编程中,有时需要在一个方法返回两个个或两个以上的数据,用下面的几种方法都可以实现: 1 使用数组的方式,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <html> <head> <title>JS函数返回多个值</title> <

JS文件中的中文在网页上显示为乱码解决方法

JS编码转换,这句话本身就是一句具有二重义的话.通常理解为JS文件里能转换编码的代码,但是,我所碰到的问题并不是这样的,是要解决JS文件本身的编码问题,它是UTF-8编码的还是ANSI编码的?在百度.谷歌上一搜,大家都是说通过JAVA后台处理来解决编码问题,试问,这样能解决JS文件本身的编码问题吗? 之所以提出JS文件本身编码问题,是因为JS文件的编码不同,造成了中文显示为乱码. 通常,在Eclipse中建立一个JS文件(含有中文),在Eclipse的编辑器中看到的中文都很正常,但是显示在网页上