Promise
对象是一个构造函数,其接受一个函数做为参数,resolve
、reject
为这个函数的参数,函数内部通常为异步执行的代码,resolve
做为异步执行完成以后成功的回调,reject
做为异步执行抛错的回调。Promise
构造函数能够理解为执行异步的过程,其resolve
和reject
为执行异步调用结果的回调函数。javascript
// 代码1 var p = new Promise((resolve, reject) => { // 执行一系列的异步执行 // some codes... if (true) { resolve("异步执行成功"); } else { reject("异步执行抛错"); } }); // fulfilled: 异步执行成功 ; 非fulfilled: 异步执行抛错
Promise
构造函数返回一个异步执行以后的promise
对象,该对象对异步的结果进一步处理。java
// 代码2 p .then((res) => { // try catch 手动抛错 try { // console.log("异步返回成功状态"); throw Error("错误代码"); } catch(e) { console.log("执行catch"); return Promise.reject(e); } }) .catch((res) => { console.log(res); // 输出上一个 then 中 catch 的 e return "这里由错误信息过去的数据"; }) .then((res) => { console.log(res); // 若上一个catch执行,输出:这里由错误信息过去的数据 })
以上代码执行结果:node
# 结果1 执行catch Error: 错误代码 at p.then (**/promise.js:77:10) at process._tickCallback (internal/process/next_tick.js:109:7) at Module.runMain (module.js:607:11) at run (bootstrap_node.js:423:7) at startup (bootstrap_node.js:147:9) at bootstrap_node.js:538:3 这里由错误信息过去的数据
由代码2能够看出,promise
对象状态为resolve
的时候,执行then
方法,并且在不抛错状况下会持续执行链式调用的then
方法,若then
方法抛出异常或者抛出返回Promise.reject()
方法,会转到执行catch
方法,若catch
方法返回的不是Promise.reject()
方法或者不抛出异常,则全部使用return
返回的数据都会做为参数传给下一个then
函数参数的参数,即代码2中的最后一个then
方法指定函数参数的res
是上一个catch
所return
的数据。es6
var p = new Promise((resolve, reject) => { resolve("ok"); }); p.then((msg) => { console.log(msg); return Promise.reject("then01抛错"); }).catch((errMsg) => { console.warn(errMsg); }).then(() => { console.log("then02再执行"); }).then(() => { console.log("then03再执行"); return Promise.reject("then03抛错"); }).catch((errMsg) => { console.warn(errMsg); return "catch02 return 给下一个then指定方法的值"; }).then((msg) => { console.log(msg); });
运行结果以下:bootstrap
这是由于then
方法和catch
方法返回的都是一个promise
对象。then
方法指定的回调函数抛出错误会被下一个catch
方法捕获,多个then
方法执行也是如此。catch
方法会捕获上一个catch
方法(若是有的话)以后抛错的错误。promise
换言之,不管是
then
方法仍是catch
方法,返回的都是一个promise
对象,其状态取决于上一个方法指定的函数是否顺利执行或者没有返回Promise.reject()
。浏览器
Promise
状态一旦Promise的状态变为resolved或者rejected,就会永久保持该状态,不会再变。bash
var p = new Promise((resolve, reject) => { resolve("ok"); throw new Error("wrong"); }); p.then((msg) => { console.log(msg); }).catch((errMsg) => { console.warn(errMsg); }); // ok
在Promise的参数函数中,因为先判定了resolved状态,因此在以后只会执行then
函数,后面抛出的错误会等于没抛出来。异步
另外,“事件循环”会对抛出的结果有影响。函数
var p = new Promise((resolve, reject) => { resolve("ok"); setTimeout(() => { throw new Error("wrong"); }, 0); }); p.then((msg) => { console.log(msg); }).catch((errMsg) => { console.warn(errMsg); }); // ok // 浏览器抛出的错误 // index.js:4 Uncaught Error: wrong // at setTimeout (index.js:4) // setTimeout @ index.js:4
在本轮“事件循环”中,promise
对象p
先执行,因此构造函数Promise
的指定函数先输出‘ok’;在进入到下一次的“事件循环”的时候,因为Promise
函数体已经执行完毕,故后面抛出的错误是在Promise
函数体外抛出的,Promise
函数体没法捕获到这个错误。
Promise.resolve()
接受一个参数,其返回一个promise
对象的状态会由于传入的参数的不一样而不一样。
空
返回一个状态为resolved
的promise对象,也就是下一步会执行then
方法。
var p = Promise.resolve(); p.then((res) => { console.log("then"); }).catch((res) => { console.log("catch"); }); // then
thenable
对象
var thenable = { then: function (resolve, reject) { console.log("当即执行thenable的then的方法" + Date.now()); resolve("判定以后的信息"); } } var p = Promise.resolve(thenable); p.then((res) => { console.log(res); }); // 当即执行thenable的then的方法1494485393447 // 判定以后的信息 // 至关于 var p = new Promise(function (resolve, reject) { console.log("当即执行thenable的then的方法" + Date.now()); resolve("判定以后的信息"); }); p.then((res) => { console.log(res); }); // 当即执行thenable的then的方法1494485454503 // 判定以后的信息
thenable
对象做为参数,在执行Promise.resolve(thenable)
方法的时候,会当即执行thenable
对象中的then
方法,而且其返回的Promise
对象的状态取决于thenable
对象的then
方法执行的是resolve()
仍是reject()
。这种状况下,就至关于Promise
构造函数以thenable
对象的then
方法做为参数,实例化一个Promise
实例。
一个非Promise
对象,且不含有then
方法的对象------非thenable
对象
var p = Promise.resolve({ a: 1 }); p.then((res) => { console.log(res); }); // { a: 1 } var p01 = Promise.resolve('Hello Promise!'); p01.then((res) => { console.log(res); }); // Hello Promise!
这种状况下,Promise.resolve()
的状态为resolved
,其接收的参数会做为then
方法指定函数的参数。
Promise对象
var p01 = new Promise((resolve, reject) => { reject('Throw some error! Come on! You bite me.'); }); var p = Promise.resolve(p01); p.then((res) => { console.log("这是then方法"); }).catch((errMsg) => { console.log(errMsg); }); // Throw some error! Come on! You bite me.
传入的是一个Promise
对象,Promise.resolve()
返回的对象的状态就是传入的Promise
对象的状态。
Promise.reject(reason)
方法一样返回一个状态为rejected
的Promise
对象实例。值得注意的是,参数reason
(Promise
状态rejected
的缘由)不管是什么值,都会传给返回的Promise
对象的catch方法指定的函数做为参数。
var p = Promise.reject('Throw some error! Come on! You bite me.'); p.then((res) => { console.log("这是then方法"); }).catch((errMsg) => { console.log(errMsg); }); // Throw some error! Come on! You bite me.
var imgPromise = function (url) { return new Promise((resolve, reject) => { var img = new Image(); img.src = url; img.onload = resolve; img.onerror = reject; }); } imgPromise("http://imgurl") .then((res) => { console.log("图片加载完成"); }) .catch((res) => { console.log("图片加载失败"); }):