Promise 是异步编程的一种解决方案。javascript
Promise
对象两个特色:对象的状态不受外界影响。Promise
对象表明一个异步操做,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。java
一旦状态改变,就不会再变。称为 resolved[已定型]。
从pending变为fulfilled 或者 从pending变为rejectedes6
Promise
缺点:没法取消 Promise ,一旦新建它就会当即执行,没法中途取消。
若是不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
当处于 pending 状态时,没法得知目前进展到哪个阶段(刚刚开始仍是即将完成)。编程
//新建promise对象 两个参数resolve, reject const promise = new Promise(function(resolve, reject) { if (/* 异步操做成功 */){ resolve(value); } else { reject(error); } }); promise .then( //promise的resolved回调函数 result => {console.log("resolved: ", result)}, //then的第一方法成功回调, err => console.log("rejected: ", err) //then的第二个失败回调 (可选) 不推荐 更推荐在catch捕获错误 .catch(error => {···}) //promise的resolved回调函数 .finally(() => {···}); //在执行`then`或`catch`后,都会执行`finally`回调
第一个参数是resolved
状态的回调函数,
第二个参数(可选)是rejected
状态的回调函数json
getJSON("/post/1.json").then( post => getJSON(post.commentURL) ).then( comments => console.log("resolved: ", comments), err => console.log("rejected: ", err) ); 第一个`then`方法指定的回调函数,返回的是另外一个`Promise`对象。 第二个`then`方法指定的回调函数,就会等待这个新的`Promise`对象状态发生变化。若是变为`resolved`,就调用第一个回调函数, 若是状态变为`rejected`,就调用第二个回调函数。
Promise.prototype.catch() 是.then(null, rejection)或.then(undefined, rejection)的别名。数组
指定reject的回调
。在执行resolve的回调(也就是上面then中的第一个参数)时,若是抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中
。基本写法 // 写法一 const promise = new Promise(function(resolve, reject) { try { throw new Error('test'); } catch(e) { reject(e); } }); promise.catch(function(error) { console.log(error); }); // 写法二 const promise = new Promise(function(resolve, reject) { reject(new Error('test')); }); promise.catch(function(error) { console.log(error); });
(1)Promise内部报错 则then的第二个函数和catch就近原则能捕获到promise
const promise = new Promise((resolve, rejected) => { throw new Error('test'); }); //状况一:既有第二个函数也有catch时 就近原则 promise.then(res => { }, err => { console.log('我比较近我能捕获到',err); }).catch(err1 => { console.log(err1); }); 运行结果:我比较近我能捕获到,test //状况二:只有第二个函数或只有catch 那就是它能捕获
(2) then
的第二个的函数捕获不了then中的第一个函数抛出的错误
,然后续的.catch
能够捕获。服务器
Promise.resolve() .then(function success (res) { throw new Error('error') }, function fail1 (e) { console.error('fail1: ', e)~~~~ }) .catch(function fail2 (e) { console.error('fail2: ', e) }) 运行结果: fail2: Error: error at success (...) at ...
如服务器使用 Promise 处理请求,而后使用finally
方法关掉服务器app
server.listen(port) .then(result => {···}) .finally(server.stop);
全返回回来才回调操做
// 生成一个Promise对象的数组 const promises = [2, 3, 5, 7, 11, 13].map(function (id) { return getJSON('/post/' + id + ".json"); }); Promise.all(promises).then(function (posts) { }).catch(function(reason){ });
若是子promise没有报错了 可是子promise没有定义catch, 就会调用promise.all的catch。异步
只要有一个回来就回调操做
// 有一个图片加载完就添加到页面 function loadImg(src){ return new Promise((resolve,reject)=>{ let img=document.createElement('img'); img.src=src; img.onload=function(){ resolve(img); } img.onerror=function(err){ reject(err); } }) } function showImgs(img){ let p=document.createElement('p'); p.appendChild(img); document.body.appendChild(p) } Promise.race([ loadImg('http://www.baidu.com/1.png'), loadImg('http://www.baidu.com/567751/2.png'), loadImg('http://www.baidu.com/567751/3.png') ]).then(showImgs)
转为Promise对象
(1)参数是一个 Promise 实例 原封不动地返回这个实例
(2)不带有任何参数 直接返回一个resolved
状态的 Promise 对象
(3)参数是一个thenable
对象(即具备then
方法的对象)
Promise.resolve方法会将这个对象转为 Promise 对象,而后就当即执行thenable对象的then方法。
//`thenable`对象指的是具备`then`方法的对象 let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
(4)参数不是具备then
方法的对象,或根本就不是对象
若是参数是一个原始值,或者是一个不具备then
方法的对象,则Promise.resolve
方法返回一个新的 Promise 对象,状态为resolved
。
const p = Promise.resolve('Hello'); p.then(function (s){ console.log(s) }); // Hello
转为Promise对象 且状态是rejected
和Promise.resolve方法同样,Promise.reject方法产生的Promise对象的状态是rejected的。
const p = Promise.reject('出错了'); // 等同于 const p = new Promise((resolve, reject) => reject('出错了')) p.then(null, function (s) { console.log(s) }); // 出错了
mark一下 仅供参考 欢迎更正补充 Thanks
参考资料:
阮一峰:https://es6.ruanyifeng.com/?search=String.raw&x=0&y=0#docs/promise#Promise-all
关于promise的十道题目:https://juejin.im/post/5a0406...
性感的Promise,拥抱ta而后扒光ta:https://juejin.im/post/5ab20c...
通俗易懂的Promise:https://juejin.im/post/5afe6d...