前言:异步编程对JS语言来说是很重要的,JS执行环境是单线程的,如果没有异步,但凡执行中遇到卡死,页面就无法使用。

传统方法:
1.回调函数
2.事件监听
3.发布/订阅
4.Promise对象
Generatror函数将JS异步带入了全新阶段

异步:简单说就是一个任务不是连续完成的,可以理解为该任务被分成了两段,先执行第一段,然后去执行其他任务,等做好准备再执行第二段.比方(一个任务读取文件进行处理,任务第一段是发出请求,然后程序执行其他任务,等到操作系统返回文件再接着执行第二段)
同步:相应的,连续执行叫做同步,不能再过程中插入其他任务,只能等待响应

回调函数:JS对异步编程的实现就是回调,所谓回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务时便直接调用这个函数。

读取文件进行处理的代码如下:
    fs.readFile('etc/file','utf-8',function(err,data){
        if(err) throw err;
        console.log(data);
    })
上面代码中readFile函数的第三个参数就是回调函数,也就是任务的第二段,等到操作系统返回etc/file文件以后,回调函数才会执行。其中一个有趣的问题是:为什么Node约定回调函数的第一个参数必须是错误对象呢err(如果没有错误,该参数就是null)呢? 答案是:执行分成两段,第一段执行完以后,任务所在的上下文环境就已经结束了,再有以后抛出错误,其原来的上下文环境已经无法捕捉,因此只能当做参数被传入第二段。

Promise :回调函数本身并没有局什么问题,它的问题出现在多个回调函数嵌套上,假定读取A文件之后读取B文件代码如下

fs.readFile('fileA','utf-8',function(err,data){

  fs.readFile('fileB','utf-8',function(err,data){     
    
    })
 })
 

不难想象如果依次读取以上两个文件,就会出现多重嵌套,代码不是纵向发展,而是横向发展,很快就是混乱,多个异步操作形成的强耦合,只要有一个操作需要修改,它的上层回调函数和下层回调函数都要更着修改,这种情况我们称之为“回调地狱”(callback hell);
Promise对象就是为了解决这个问题而被提出的,它将回调函数的嵌套改写成了链式调用,采用Promise连续读取多个文件的写法如下。
var readFile =require('fs-readFile-Promise')

readFile(fileA).then(function(data){
    console.log(data.toString())
}).then(function(){
   readFile(fileB);
}).then(function(data){
    console.log(data.toString())
}).catch(function(err){
    console.log(err)
})
**promise**提供了then方法加载回调函数,catch方法捕捉执行过程中的错误,promise 的写法只是回调函数的改进,使用.then方法以后异步任务两段执行更清晰,除此之外并无新意。
Promise最大的问题是代码冗余,原来的任务被promise包装后,无论什么操作,一眼看去都是.then的堆积。

  
    



Jackie龙
51 声望2 粉丝

Any application that can be written in javeScript,will eventually be written in javeScript


引用和评论

0 条评论