异步编程有哪几种方法来实现

异步编程有哪几种方法来实现?

1.背景介绍

        JavaScript的执行环境是单线程的,单线程的好处是执行环境简单,不用去考虑诸如资源同步,死锁等多线程阻塞式编程等所需要面对的恼人的问题。但带来的坏处是当一个任务执行时间较长时,后面的任务会等待很长时间。在浏览器端就会出现浏览器假死,鼠标无法响应等情况。所以在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应。所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的、同步的),每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。既然Javascript是单线程的,那它又如何能够异步的执行呢?

2.知识剖析


2.1异步编程有哪几种方法

      1.回调函数

     2.事件监听

     3.Promises对象

     4.发布/订阅(观察者模式)


2.2回调函数

         这是异步编程最基本的方法。回调函数的优点是简单,轻量级(不需要额外的库)。缺点是各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数,而且,如果再嵌套多几层,代码会变得多么难以理解

      这个被称之为“回调函数噩梦”(callback hell)!!!

 function fn1(f){ alert(1); f(); }; 

function fn2(f){ alert(2); f(); }; 

function fn3(){ alert(3); }; 

fn1(function(){ fn2(fn3); });              

       注意 区分 回调函数和异步 回调并不一定就是异步。他们自己并没有直接关系。 简单区分 同步回调 和 异步回调

2.3

     事件监听

    $("#clickity").on("click", function (e) { console.log("xxxxx");

       采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化。缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。

2.4

Promises对象

       Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。 简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

            f1().then(f2); 这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。 比如,指定多个回调函数:   f1().then(f2).then(f3);

      再比如,指定发生错误时的回调函数:f1().then(f2).fail(f3); 而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。

3.常见问题

    何时使用异步?

4.解决方案

     在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,"异步模式"甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

 5.编码实战

  

function fn1( f) {
alert( 1);
f();
};

function fn2( f) {
alert( 2);
f();
};

function fn3() {
alert( 3);

};

fn1( function () {
fn2(fn3);
});

//回调函数
// 同步回调
function A( callback){
console. log( "I am A");
callback(); //调用该函数
}
function B(){
console. log( "I am B");
}
A(B);

// 异步回调
function f1( n, callback) { 
setTimeout( function () {
var count = 0,
i, j;

for (i = n; i > 0; --i) {
for (j = n; j > 0; --j) {
count += 1;
}
};
console. log( 1);

}, 1000)
callback();
console. log( 2);
}

function f2() {
console. log( "函数f2")
}


function f3() {
console. log( 3)
setTimeout( function () {
console. log( 4)
}, 5000)
console. log( 5)
}

f1( 100000, f3);
f2();
f3();

//事件监听



function fb() {
alert( 9999)
}
$( "#b1"). on( 'click', fb);



// promise

function f7() {
var def = $. Deferred();
setTimeout( function () {
// f1的任务代码
console. log( "this is f7");
def. resolve();
}, 500);
return def. promise();
}

function f8() {
console. log( "this is f8");
}

function f9() {
console. log( "this is f9");
}
f7(). then(f8). then(f9);

6.扩展思考

    异步的好处: 
        1、异步流程可以立即给调用方返回初步的结果。
         2、异步流程可以延迟给调用方最终的结果数据,在此期间可以做更多额外的工作,例如结果记录等等。
       3、异步流程在执行的过程中,可以释放占用的线程等资源,避免阻塞,等到结果产生再重新获取线程处理。
        4、异步流程可以等多次调用的结果出来后,再统一返回一次结果集合,提高响应效率。


7.参考文献

                https://www.jb51.net/article/78757.htm 

            http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html

8.更多讨论

1,问:何时使用异步

答:耗时较长的任务,影响后面任务执行,造成浏览器失去响应,都可以使用异步,

2,问:回调函数一定是异步吗

答:不一定,回调函数有同步回调和异步回调,

3,问:promise是什么

答:Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。 简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数,具体知识可以去网上详细了解一下promise。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值