美文网首页
Javascript的异步和回调

Javascript的异步和回调

作者: web佳 | 来源:发表于2018-03-19 19:08 被阅读0次

1、同步与异步

         foo();

         bar();

         程序运行一般是同步的(synchronous),即按照书写的顺序执行。在上述例子中,bar 方法会在 foo 方法执行完之后,再执行。

         异步(asynchronous)与同步相对,即在前一个方法未执行完时,就开始运行后一个方法。在上述例子中,先执行 foo 方法,foo 方法没执行  完,就开始执行 bar 方法。

          总而言之,同步就是顺序执行,异步就是不完全按顺序执行。

          异步的好处

          从异步的概念中可以发现,程序异步运行,可以提高程序运行的效率,不必等一个程序跑完,再跑下一个程序,特别当这两个程序是无关的时候。两个程序在一定时间内,可以是同时运行的。写服务器的时候应该会碰到很多这样的例子。可以想象,如果服务器的程序都是同步的,那并发什么的就不存在了吧。

2、阻塞与非阻塞

         ①、 阻塞就是说一个程序没运行完,它后面的程序是无法运行的。

         ②、  而非阻塞则相反,一个程序如果因为各种原因(网络、代码量等)没运行完的时候,其他的程序也是可以继续运行的。

3、单线程与多线程

           ①、 单线程是指程序运行只有一个通道,不同的方法需要排队执行。

           ②、而很多语言都可以提供多线程的功能,相当于开了几个通道运行程序,使得程序可以在不同的线程中运行,不会相互影响。

4、多线程、非阻塞、异步

            从上述基本概念中可以发现,异步如果发生在多线程语言中,会十分自然且符合逻辑。异步本质上应该就是多线程语言的产物。因为只有在多线程语言中才能够实现程序之间相互不干扰,不产生阻塞。

5、JS 中的异步

           有了上面的一些基本概念,那么下面来说说正题,JS中的异步。

           我们都知道 JS 是一个单线程的语言,永远只有一个通道在运行程序。那么既然它是个单线程又如何会有异步呢?

           JS 中所谓的异步,应该被称为伪异步(pseudo asynchronous)。这是因为 JS 语言中的异步,会产生阻塞,并会相互干扰。

            模拟 JS 中异步的方法 —— setTimeout

            我们来看一下 setTimeout 如何模拟 JS 中的异步:

            var foo =function(){

                    console.log('foo begins');

                     setTimeout(function(){

                        console.log('foo finishes'); 

                     },1000);

                    };

            var  bar =function(){

                console.log('bar executed'); 

             }

            foo();

            bar();

上述过程执行的时候,会依次打印出

    //foo begins

    //bar executed

    //foo finished

        所以,在上述代码块中,在前一方法(foo)执行时,后一方法(bar)也可以执行。符合异步的基本概念,程序并不按顺序执行。

说是模拟是因为,你可以把 console.log('foo begins'); 理解成会运行 1 秒的一个代码行,运行完后,会跳出foo finishes。而中间这 1 秒运行的时候,后面的 bar 方法也是可以运行的。这样就模拟了一个异步的效果。

6、JS 中异步的方法存在的问题 —— 阻塞与干扰

        我们将上述代码块稍做修改

        var foo=function(){

                console.log('foo begins');

                setTimeout(function(){

                    console.log('foo finished');

                },1000)

          }

            var  bar=function(){

                while(true){

                            }

                };

            foo();

            bar();

               你会发现 1 秒之后 foo finishes 并没有被打印出来。这是因为 bar 方法是个死循环,使得 js 引擎假死,导致了 foo 方法也没有被运行完。如果是多线程的异步,假死的应该是运行 bar 方法的线程,而 foo 方法仍然会按预期打印出 foo finishes。当然了,其实这个死循环也只是模拟 bar 方法块程序运行的时间将很长。实际上,如果 bar 方法运行的时间超过了 1 秒,比方说是 5 秒,那么 foo finishes 也将在 5 秒之后被打印出来。这个本质上取决于 JS 单线程程序块按队列执行的特性。

所以 JS 中的异步并不能像普通的异步一样,实现非阻塞和不干扰。

7、JS 中异步的一些实现方法

            虽然 JS 中的异步有其先天的缺陷,但是这种异步的思想,仍然能被 JS 程序开发人员所借鉴。毕竟,异步是可以大大提高程序运行效率的。

            也正是由于 JS 本身是单线程程序的关系,所以 JS 中异步的实现,并不能像其他语言一样,简单地多开个线程就可以解决。

            目前我看的集中方法主要有回调、事件类方法、promise等。

8、回调

        先说说回调是什么吧。

        回调(callback)这种名词就跟函数(function)一样,乍一看是比较难懂的,至少我是这样的。

        根据sf上这个问答的解释,可以明确,把一个函数作为参数传入到另一个函数中,那么这个作为参数的函数就叫做回调函数。如:

       var foo =function(params,callback){

            // foo method

          return callback(5);

        };

        foo(5,function(data){

            console.log(data)

        });

其中,bar 就是一个回调函数。当然了,按我个人的理解,应该说是 bar 是 foo 的回调函数

相关文章

  • Nodejs 请求中的异步陷阱

    异步和回调 JavaScript中有一些居家旅行必备的异步函数, 例如 setInterval, setTimeo...

  • Javascript的异步和回调

    1、同步与异步 foo(); bar(); 程序运行一般是同步的(synchronous)...

  • 《全栈工程师修炼指南》学习笔记 15

    异步编程 JavaScript 回调函数容易引起回调地狱 后来有了 Promise,可以将回调函数以 then 的...

  • Javascript异步回调

    同步模式与异步模式 Javascript语言执行环境是“单线程”,一次执行一个任务,并且按照顺序依次执行。但是遇到...

  • Promise链式调用解决回调地狱

    什么 回调地狱 ? 异步JavaScript,或者说使用回调的JavaScript,很难直观地得到正确的结果。很多...

  • Promise快速上手

    概述 回调函数是JavaScript异步编程的根基,但如果我们直接使用传统回调方式去完成复杂的异步流程,就无法避免...

  • 含答案的面试题总结

    1. 说说JavaScript中有哪些异步编程方式? 1. 回调函数 回调函数是异步编程的基本方法。其优点是易编写...

  • Javascript中的异步和回调

    异步 我们都知道Javascript语言的执行环境是"单线程",所谓"单线程"就是指一次只能完成一件任务。如果有多...

  • 异步

    JavaScript异步编程解决方案笔记 JavaScript Promise迷你书 Node.js回调黑洞全...

  • JavaScript异步编程__“回调地狱”的一些解决方案

    异步编程在JavaScript中非常重要。过多的异步编程也带了回调嵌套的问题,本文会提供一些解决“回调地狱”的方法...

网友评论

      本文标题:Javascript的异步和回调

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