Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in D:\site\54cainiao\web\config\function.php on line 295 ES6中Promise的使用方法实例总结 - 54菜鸟
11

ES6中Promise的使用方法实例总结

  • 时间:2020-02-18 15:08 编辑:54菜鸟 来源: 阅读:2098
  • 扫一扫,手机访问
摘要:本文实例讲述了ES6中Promise的使用方法。分享给大家供大家参考,具体如下:在javascript中,代码是单线程执行的,对于一些比较耗时的IO操作,都是通过异步回调函数来实现的。但是这样会存在一个问题,当下一个的操作需要上一个操作的结果

本文实例讲述了ES6中Promise的使用方法。分享给大家供大家参考,具体如下:


在javascript中,代码是单线程执行的,对于一些比较耗时的IO操作,都是通过异步回调函数来实现的。


但是这样会存在一个问题,当下一个的操作需要上一个操作的结果时,我们只能把代码嵌到上一个操作的回调函数里,这样一层嵌一层,最终形成回调地狱。


$.get('/login.php', function (login) {

  $.get('/user.php', function (user) {

    $.get('/info.php', function (info) {

      //代码就这样一层嵌一层,不够直观,维护也麻烦

    });

  });

});

为了解决这种问题,ES6中就提供了Promise方法来解决这种问题。


Promise是一个构造函数,通过它,我们可以创建一个Promise实例对象。


let p = new Promise(function (resolve, reject) {

  setTimeout(() => {

    console.log('OK');

    resolve('OK');

  }, 1000);

});

Promise构造函数接受一个函数作为参数,这个函数有两个参数,resolve和reject。


resolve函数是将Promise的状态设置为fulfilled(完成),reject函数是将Promise的状态设置为rejected(失败)。


上述代码,我们并没有进行任何调用,当运行时,间隔1秒后输出了'OK'。所以这里需要注意,我们通常使用Promise时,需要在外层再包裹一层函数。


let p = function () {

  return new Promise(function (resolve, reject) {

    setTimeout(() => {

      console.log('OK');

      resolve('OK');

    }, 1000);

  });

};

p();

上面的代码p();返回的是一个Promise实例对象,Promise对象上有 then() , catch() , finally() 方法。


then方法有两个参数,onFulfilled和onRejected,都是函数。


onFulfilled用于接收resolve方法传递过来的数据,onRejected用于接收reject方法传递过来的数据。


let p = function () {

  return new Promise(function (resolve, reject) {

    setTimeout(() => {

      if (Math.random() > 0.5) {

        resolve('OK');

      } else {

        reject('ERR');

      }

    }, 1000);

  });

};

p().then(function (data) {

  console.log('fulfilled', data);

}, function (err) {

  console.log('rejected', err);

});

then()方法总是会返回一个Promise实例,这样我们就可以一直调用then()。


在then方法中,你既可以return 一个具体的值 ,还可以return 一个Promise对象。


如果直接return的是一个数据,那then方法会返回一个新Promise对象,并以该数据进行resolve。


let p = function () {

  return new Promise(function (resolve, reject) {

    resolve(1);

  });

};

p().then(function (data) {

  console.log(`第 ${data} 次调用`);

  //注意这里直接返回的值

  //then会创建一个新的Promise对象,并且以返回的值进行resolve

  //那么该值会被下面的then方法的onFulfilled回调拿到

  return ++data;

}).then(function (data) {

  console.log(`第 ${data} 次调用`);

  return ++data;

}).then(function (data) {

  console.log(`第 ${data} 次调用`);

  return ++data;

});

如果返回的是一个Promise对象,请看下面代码。


let p = function () {

  return new Promise(function (resolve, reject) {

    resolve(1);

  });

};

p().then(function (data) {

  console.log(`第 ${data} 次调用`);

  return new Promise(function (resolve, reject) {

    resolve(++data);

  });

}).then(function (data) {

  console.log(`第 ${data} 次调用`);

  return new Promise(function (resolve, reject) {

    resolve(++data);

  });

}).then(function (data) {

  console.log(`第 ${data} 次调用`);

  return new Promise(function (resolve, reject) {

    resolve(++data);

  });

});

其实效果与直接返回值的是一样的。


即然then()可以进行链式操作,那我们最早之前的回调地狱写法,就可以通过它进行改进了。


function login() {

  return new Promise(function (resolve, reject) {

    $.get('/login.php', function (result) {

      resolve(result);

    });

  });

}

function user(data) {

  return new Promise(function (resolve, reject) {

    $.get('/user.php', function (result) {

      resolve(result);

    });

  });

}

function info(data) {

  return new Promise(function (resolve, reject) {

    $.get('/info.php', function (result) {

      resolve(result);

    });

  });

}

login().then(function (data) {

  console.log('处理login');

  //把login异步处理获取的数据,传入到下一个处理中。

  return user(data);

}).then(function (data) {

  console.log('处理user');

  //把user异步处理获取的数据,传入到下一个处理中。

  return info(data);

}).then(function (data) {

  console.log('处理info');

});

这样修改后,回调地狱层层嵌套的结构就变的清晰多了。上述代码是伪代码。


Promise对象还有一个catch方法,用于捕获错误,该方法与 then(null, onRejected) 等同,是一个语法糖。



let p = function () {

  return new Promise(function (resolve, reject) {

    resolve('开始');

  });

};

p().then(function (data) {

  console.log('1');

  return new Promise(function (resolve, reject) {

    reject('错误1');

  });

}).then(function (data) {

  console.log('2');

  return new Promise(function (resolve, reject) {

    reject('错误2');

  });

}).then(function (data) {

  console.log('3');

  return new Promise(function (resolve, reject) {

    reject('错误3');

  });

}).catch(function (reason) {

  console.log(reason);

});

注意,一旦操作中有错误发生,则会进入到catch中,后面的操作将不再执行。


Promise对象内部自带了try catch,当代码运行时错误,会自动以错误对象为值reject,并最终被catch捕获。


let p = function () {

  return new Promise(function (resolve, reject) {

    resolve('开始');

  });

};

p().then(function (data) {

  //注意这里打印了一个未定义的变量

  console.log(a);

}).catch(function (reason) {

  //这里会捕获到错误

  console.log('rejected');

  console.log(reason);

});

Promise还提供了,all(),race(),reject(),resolve()等在构造函数上的方法,调用这些方法并不需要实例化对象。


all()方法,可以让我们并行的执行异步操作,直到所有操作完成了,才执行回调。


function fn1() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn1');

    }, 1000);

  });

}

function fn2() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn2');

    }, 2000);

  });

}

function fn3() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn3');

    }, 3000);

  });

}

//all会等待所有操作完成,会把所有操作的结果放到一个数组中,传给then。

Promise.all([fn1(), fn2(), fn3()]).then(function (data) {

  console.log(data);

});

race()方法是谁先处理完,就以谁为准,把最先处理完的结果传给then。


function fn1() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn1');

    }, 1000);

  });

}

function fn2() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn2');

    }, 2000);

  });

}

function fn3() {

  return new Promise(function (resolve, reject) {

    setTimeout(function () {

      resolve('fn3');

    }, 3000);

  });

}

//race是以谁先处理完,就以谁为准,fn1最先处理完,那fn1的结果会传给then

//注意这里fn2和fn3还是会执行,不过不会进入then了

Promise.race([fn1(), fn2(), fn3()]).then(function (data) {

  console.log(data);

});

reject()方法,返回一个带有拒绝原因reason参数的Promise对象。



// Promise.reject('错误')

// 等同于

// new Promise(function(resolve, reject) {

//   reject('错误');

// });

let p = Promise.reject('错误');

p.then(function (data) {

}).catch(function (reason) {

  console.log(reason);

});

resolve()方法,根据传入的值返回一个Promise对象。



//如果传入的参数是普通值,则返回一个新Promise对象,并以该值resolve

let p1 = Promise.resolve('OK');

p1.then(function (data) {

  console.log(data);

});

//如果传入的参数是一个Promise对象,则原封不动的返回该Promise对象

let obj = new Promise(function (resolve, reject) {

  resolve('我是Promise对象');

});

let p2 = Promise.resolve(obj);

p2.then(function (data) {

  console.log(data);

  console.log(p2 === obj);

});

//如果传入的参数是一个thenable对象(带有then方法),

//会转换成Promise对象,并执行thenable对象的then方法

let then = {

  then(resolve, reject) {

    resolve('我是thenable对象');

  }

}

let p3 = Promise.resolve(then);

p3.then(function (data) {

  console.log(data);

});

//如果什么参数都不传入,则返回状态为resolved的Promise对象

let p4 = Promise.resolve();

p4.then(function (data) {

  console.log(data);

}).catch(function (reason) {

  console.log(reason);

});


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【织梦cms|织梦技巧】织梦默认作者和默认泉源修改(2021-12-08 10:11)
【织梦cms|织梦技巧】 织梦dedecms差异栏目导航显示差异样式的方式(2021-12-08 10:09)
【织梦cms|织梦技巧】织梦dede新建模型中自定义联动类别调用(2020-03-01 13:52)
【织梦cms|织梦技巧】织梦CMS标签中出现“系统无此标签,可能已经移除”(2020-03-01 13:51)
【织梦cms|织梦技巧】dedecms织梦系统后台验证码图片不显示的解决方法(2020-03-01 13:51)
【织梦cms|织梦技巧】dedecms更新文章会出现空白页(2020-03-01 13:50)
【织梦cms|织梦技巧】让织梦dedecms搜索结果按照点击数排序(2020-03-01 13:48)
【织梦cms|织梦技巧】在dedecms织梦内容页中调用文章缩略图(2020-03-01 13:47)
【织梦cms|织梦技巧】在dedecms织梦添加自制的背景图片(2020-03-01 13:47)
【织梦cms|织梦技巧】修改织梦dedecms幻灯片属性(2020-03-01 13:46)