JavaScript:异步但不是多线程?

3

我有以下内容:

function NumberFormatter(){
   ...
   function helper(){
   ...
       var tempvar;
   ...
   }
   function format(num){
   ...
       helper()
   ...
   }
}

//there is a single instance of FT

var FT = new NumberFormatter()
FT.format(123)

对象的状态没有改变。
在多线程环境下,如果从两个不同的位置几乎同时调用format(),那么这段代码会失败吗?
是否有一种简单的方法来锁定对象,还是持有1000个实例更好?
答案:(总结所有发布的内容...)
- 不会失败(因为JavaScript中没有真正的多线程)。 - 没有锁定对象的方法,也不需要。 - 可以只有一个实例。不需要创建1000个实例。
对于那些不相信的人,这是证明代码
<script type='text/javascript'>

    function get_random_color() {
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++ ) {
            color += letters[Math.round(Math.random() * 15)];
        }
        return color;
    }

    setInterval('document.getElementById("a").style.backgroundColor=get_random_color()', 10)

    //***  setInterval() stops when heavy calculations are done   ***//

    document.getElementById("b").onclick = function(){
        for(var i=0;i<10000000; i++){
            Math.atan2(Math.round(1000))
        }
    }
</script>


4
据我所知,在JavaScript中实际上无法获取多线程上下文,因此您不必担心它。 - Travis Gockel
2
@Dan:JavaScript 中的多线程?我认为 JavaScript 是在单个执行线程中运行的... - Nobita
@Olegas 如果您使用几个 setTimeout,系统会将它们排队吗? - Andrey
虽然在JavaScript中可以进行多线程处理,但是两个线程只能发送“消息”,并且无法访问彼此的对象:一个线程=一个上下文。 - tcooc
Web Workers不是多线程的吗? - KooiInc
显示剩余3条评论
3个回答

4

有两点需要注意。首先,只有在处理外部资源或更改对象状态时才需要担心并发问题。由于调用formatNum不会更改NumberFormatter的状态,所以绝对没有什么可担心的。

其次,JavaScript不支持多线程,所以这是一个无关紧要的问题。


对象的状态没有改变。我想知道的唯一事情是:当format()方法还没有完成运行时,它是否可以再次执行? - Dan
@Dan:不可能发生这种情况,因为在当前执行行停止之前,没有其他代码可以执行。JavaScript不支持多线程。 - Eric

0

我认为你应该检查一下你的代码。变量FT未定义,因为NumberFormatter没有返回值。format()将会抛出异常。

对于单个实例,为什么不直接创建像这样的东西:

var FT = new function (){
   this.helper = function (x){
   }
   this.format = function (num){
   }
}

FT.format(123);

还有一件事: JavaScript 不使用多线程,也不能同时执行代码。所有 JavaScript 代码都以非常智能的方式排队。
一个简单的例子:
setTimeout(function(){
   alert("hi");
},0);
while(true);

你永远不会收到“hi”消息。所有代码必须先执行,然后才能执行其他代码!JavaScript 也不会暂停代码的执行来运行其他代码,然后恢复第一个代码。对于我的糟糕解释感到抱歉!

因为我想创建一个对象的单个实例,该对象将整数格式化为某些字符串表示形式。 - Dan
无法同时执行代码。 - Dan

0
JavaScript是一种异步语言,总是运行在单线程上。Douglas Crockford有一个关于JavaScript同步性的精彩幻灯片:

http://www.slideshare.net/douglascrockford/crockford-on-javascript-scene-6-loopage

由于JavaScript在单个线程上运行,同一函数被同时调用的情况几乎是不可能的。你的代码应该没问题。

另外,如果你想要一个函数来帮助你格式化,那么返回一个对象,里面包含公共和私有方法怎么样?这将使你更接近单例模式:

var NumberFormatter = (function() {

    // this method is private
    var helper = function(x) {

    };

    // all methods in here are public
    return {
        format: function(num) {
            helper();
        }
    };
})();

var FT = NumberFormatter.format(123);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接