先直接上图,打印一下Promise对象,观察下Promise是什么javascript
console.dir(Promise)
能够知道,Promise是一个构造函数,有着reject、resolve函数。prototype有then、catch等方法,说明了只要是Promise对象都会有这两个方法。html
Promise构造函数是传入一个函数java
var promise = new Promise((resolve, reject) => { setTimeout(function () { console.log('执行完成'); resolve('随便什么数据'); }, 2000); }); result: 执行完成
传入的函数有两个参数:resolve、reject,分别表示异步操做执行成功后的回调函数和异步操做失败后的回调函数。其实这里用“成功”和“失败”来描述并不许确,按照标准来说,resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected。不过在咱们开始阶段能够先这么理解,后面再细究概念。git
运行以上代码,发现promise并无调用,只是new了一个Promise,对应的传入函数的代码就已经执行了。所以,咱们一般都是把Promise包在一个函数中,在须要的时候才去运行这个函数,如:es6
function f() { var promise = new Promise((resolve, reject) => { setTimeout(function () { console.log('执行完成'); resolve('随便什么数据'); }, 2000); }); return promise } f() result: 执行完成
这时引出两个问题。为何须要大费周章的包装这样的一个函数?resolve有什么用?编程
f().then(function(data){ console.log(data); //后面能够用传过来的数据作些其余操做 //...... });
在f()的返回上能够直接调用then方法,then接收一个参数,是函数,而且会拿到咱们在f中调用resolve时传入的参数。运行这段代码,会在2秒后输出“执行完成”,紧接着输出“随便什么数据”。promise
这时,咱们恍然大悟了,原来then调用的function至关于咱们以前写的回调函数,至关因而这种形式:ecmascript
function runAsync(callback){ setTimeout(function(){ console.log('执行完成'); callback('随便什么数据'); }, 2000); } runAsync(function(data){ console.log(data); });
那使用Promise有什么好处呢?咱们不妨考虑一个问题,若是callback函数也是一个异步操做,并且执行完后也须要有相应的回调函数,可能会变成 runAsync(function(data,function(data){}){.....})。看起来十分丑陋,假如使用Promise代码就不会这么丑陋了~异步
Promise的优点在于,能够在then方法中继续写Promise对象并返回,而后继续调用then来进行回调操做。函数
因此,从表面上看,Promise只是可以简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数可以及时调用,它比传递callback函数要简单、灵活的多。因此使用Promise的正确场景是这样的:
runAsync1() .then(function(data){ console.log(data); return runAsync2(); }) .then(function(data){ console.log(data); return runAsync3(); }) .then(function(data){ console.log(data); }); function runAsync1(){ var p = new Promise(function(resolve, reject){ //作一些异步操做 setTimeout(function(){ console.log('异步任务1执行完成'); resolve('随便什么数据1'); }, 1000); }); return p; } function runAsync2(){ var p = new Promise(function(resolve, reject){ //作一些异步操做 setTimeout(function(){ console.log('异步任务2执行完成'); resolve('随便什么数据2'); }, 2000); }); return p; } function runAsync3(){ var p = new Promise(function(resolve, reject){ //作一些异步操做 setTimeout(function(){ console.log('异步任务3执行完成'); resolve('随便什么数据3'); }, 2000); }); return p; } result: 异步任务1执行完成 随便什么数据1 异步任务2执行完成 随便什么数据2 异步任务3执行完成 随便什么数据3
咱们能够经过链式编程避免了包含多函数回调的状况,固然并非都须要return Promise对象,你也能够返回其余数据类型,在后面的then中就能直接直接接收到数据了,好比:
runAsync1() .then(function(data){ console.log(data); return runAsync2(); }) .then(function(data){ console.log(data); return '直接返回数据'; //这里直接返回数据 }) .then(function(data){ console.log(data); }); result: 异步任务1执行完成 随便什么数据1 异步任务2执行完成 随便什么数据2 直接返回数据
前面咱们一直都是使用resolve函数,并无使用reject函数。resolve函数是表示了“执行成功”的回调,reject函数表示“执行失败”的函数。
function runAsync1() { var p = new Promise(function (resolve, reject) { //作一些异步操做 setTimeout(function () { console.log('异步任务1执行完成'); // resolve('随便什么数据1'); reject("error") }, 1000); }); return p; } runAsync1().then((data) => { console.log('resolve'); console.log(data) }, (error, data) => { console.log('rejected'); console.log(error) }) result: 异步任务1执行完成 rejected error
须要注意的是,只要执行reject或者resolve,后面的就不会执行了,如:
function runAsync1() { var p = new Promise(function (resolve, reject) { //作一些异步操做 setTimeout(function () { console.log('异步任务1执行完成'); resolve('随便什么数据1'); reject("error") }, 1000); }); return p; }
由于resolve在reject的前面,因此只会执行resolve,不会执行reject。
ECMAScript6入门
大白话讲解Promise(一)
ECMAScript6入门
署名
广州芦苇科技Java开发团队
芦苇科技-广州专业互联网软件服务公司
抓住每一处细节 ,创造每个美好
关注咱们的公众号,了解更多
想和咱们一块儿奋斗吗?lagou搜索“ 芦苇科技 ”或者投放简历到 server@talkmoney.cn 加入咱们吧
关注咱们,你的评论和点赞对咱们最大的支持