发表于: 2017-06-11 22:26:00

1 1045


 peomise.md

javascript的异步执行

Javascript 语言的执行环境是“单线程”,每次只执行一个任务,这种模式的好处是实现起来简单,坏处是可能在一个进程卡死,导致后面的进程无法执行。为了解决这个问题,Javascript 语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。“同步模式”就是传统做法,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。这往往用于一些简单的、快速的、不涉及 IO 读写的操作。 “异步模式”则完全不同,每一个任务分成两段,第一段代码包含对外部数据的请求,第二段代码被写成一个回调函数,包含了对外部数据的处理。第一段代码执行完,不是立刻执行第二段代码,而是将程序的执行权交给第二个任务。等到外部数据返回了,再由系统通知执行第二段代码。所以,程序的执行顺序与任务的排列顺序是不一致的、异步的。
下面是几种异步模式编程的方法。

回调函数

回调函数是异步编程最基本的方法。
假定有两个函数f1和f2,后者必须等到前者执行完成,才能执行。这时,可以考虑改写f1,把f2写成f1的回调函数。

function dog(){
console.log("我爱哈士奇");
}
function sayHello(dog){
console.log("hello");
dog();
}

回调函数的优点是简单、容易理解和部署,缺点是不利于代码的阅读和维护.

事件监听

这个比较好理解,我们平时的点击按钮然后就执行点击事件里面的代码,这种注册事件的写法就算事件监听,所以不再详细介绍。

发布/订阅

“事件”完全可以理解成”信号”,如果存在一个”信号中心”,某个任务执行完成,就向信号中心”发布”(publish)一个信号,其他任务可以向信号中心”订阅”(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做”发布/订阅模式。

异步操作的流程控制

如果有多个异步操作,就存在一个流程控制的问题:确定操作执行的顺序,以后如何保证遵守这种顺序。
比如像下面这种代码:

async(1, function(value){
  async(value, function(value){
    async(value, function(value){
      async(value, function(value){
        async(value, function(value){
          async(value, final);
        });
      });
    });
  });
});

这种写法虽然保证了顺序执行,但是阅读性和维护性都特别差。

串行执行

我们可以写一个流程控制函数,一个执行完以后再执行另外一个:
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];
function series(item) {
if(item) {
async( item, function(result) {
results.push(result);
return series(items.shift());
});
} else {
return final(results);
}
}
series(items.shift());

串行执行

流程控制函数也可以是并行执行,即所有异步任务同时执行,等到全部完成以后,才执行final函数。

var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];

items.forEach(function(item) {
  async(item, function(result){
    results.push(result);
    if(results.length == items.length) {
      final(results);
    }
  })
});



返回列表 返回列表
评论

    分享到