解决回调地狱问题

好比咱们如今有个读取文件的需求,那么用nodejs,刚开始咱们的代码会这么写javascript

var fs=require('fs');
var path=require('path');


function readFile(fpath){
  fs.readFile(fpath,'utf-8',(err,data)=>{
    if(err) throw err;
    return data;
  })
}


let res=readFile('App.vue');
//这里打印为undefined 由于fs.readFile是异步的,主线程在遇到异步函数时,会将异步任务放到队列中,而后
//继续执行,因此这里获得undefined
console.log(res);

解决思路1:利用回调函数,获取异步结果vue

function readFile(fpath,callback){
  fs.readFile(fpath,'utf-8',(err,data)=>{
    if(err) throw err;
    throw new Error('er hui');
    callback(data);
  })
}
//但这里又存在一个问题,若是这个函数常常发生异常,这样的话,经过回调仍是拿不到结果的,
//咱们应该将处理的结果告诉给调用者,由调用者决定要若是处理结果,包括异常结果
readFile('App.vue',result=>{
  console.log(result)
});


改进以下,将回调函数定义成有两个参数:
function readFile(fpath,callback){
  fs.readFile(fpath,'utf-8',(err,data)=>{
    if(err) callback(err);
    callback(null,data);
  })
}
//但这里又存在一个问题,若是这个函数常常发生异常,这样的话,经过回调仍是拿不到结果的,
//咱们应该将处理的结果告诉给调用者,由调用者决定要若是处理结果,包括异常结果
readFile('App.vue2',(err,result)=>{
  if(err) throw err;
  console.log(result)
});


//改进思路3
//咱们这样写是没问题了,但对于初学者来讲可能有点很差理解,这里咱们能够规定指定的函数来处理成功的结果和异常结果
function readFile(fpath,succ,fail){
  fs.readFile(fpath,'utf-8',(err,data)=>{
    if(err) return fail(err);
    succ(data);
  })
}
readFile('App.vue',function (data) {
  console.log('succ');
  console.log(data);
},function (err) {
  console.log('fail');
  console.log(err);
});

假设有个需求,按顺序读取文件。那么咱们可能会这样写java

readFile('1.txt',function (data) {
  console.log(data);
  readFile('2.js',function (data) {
    console.log(data);
    readFile('3.js',function (data) {
      console.log(data);
    });
  });
});
这就是一个典型的回调地狱问题,
解决办法:使用ES6 的 Promise 


//1.Promise 是一个构造函数,既然是构造函数,那么咱们就能够 new Promise() 
获得一个 Promise 实例
//2.在Promise 上,有两个函数,分别叫 resolve(成功后的回调),和 reject(失败后的回调)
3,在Promise 构造函数的 prototype 属性上,有个.then 方法,也就是说只要
Promise 构造函数建立的实例,均可以访问到 .then() 方法
4,Promise 表示一个异步操做,每当咱们 new 一个 Promise 的实例,这个实例就表示一个
具体的异步操做
5,既然Promise 建立的实例,是一个异步操做,那么这个异步操做的结果,只有两种状态
5.1 异步成功了
5.2 异步失败了
5.3 因为Promise 的实例,是一个异步操做,因此内部拿到操做的结果后,没法使用return
把操做的结果返回给调用者,这时候,只能使用回调函数的形式,把成功或失败的结果返回
给调用者

每当new 一个 Promise 实例的时候,会当即执行这个异步操做中的代码
注意:经过.then 指定回调函数的时候,成功的回调函数必须传。可是失败的函数的回调
能够不传

当第一个回调报错时,后面的异步操做都不执行了,当须要第一个异步操做不影响后续回调
,须要传入异常处理函数
当后续的Promise 操做依赖于前面的Promise 操做的结果,那么可使用catch 将异常抓住
也就是说,当前面任意一个Promise 执行出错,都会被catch 抓住

function readFile(fpath){
  var promise=new Promise(function (resolve,reject) {
    fs.readFile(fpath,'utf-8',(err,data)=>{
      if(err) return reject(err);
      resolve(data);
    })
  });
 return promise;
}

var promise=readFile('Ap2p.vue');
promise.then(function (data) {
  console.log('2111')
  console.log(data)
  return readFile('main.js')
}).then(function (data) {
  console.log('222')
  return readFile('fs.js')
}).then(function (data) {
  console.log('333')
  console.log(data)
}).catch(function (err) {
  console.log('err===============')
  console.log(err)
});

补充:console.dir() 能够显示一个对象全部的属性和方法。node

相关文章
相关标签/搜索