本着互联网的分享精神,我将我对promise的理解分享给你们。 ajax
JavaScript ES6的promise方法主要应用在处理异步函数返回的结果,注意他不是将异步函数转换为同步函数,而是等异步函数有结果时在调用相应的方法进行处理。数组
then() - 它最多须要有两个参数,第一个是成功后调用的方法,第二个是失败后调用的方法。promise
catch() - 失败后调用的方法,他与then方法的失败后调用的方法相似,可是使用上有些区别,等下我会用案例讲解。服务器
all() - 接收一个数组做为参数,数组内可填写异步函数,当全部的异步函数都执行完后,会返回一个promise执行后的数组。可是有一点须要注意的是,入过参数内有一个方法报错那么他就会报错,并不会返回结果。异步
race() - 他与all的方法相似也接受一个数组做为参数(也是如若是数组内有一个方法报错那么他将会报错,不会返回结果),可是有一点不一样的是只返回一个结果,那就是哪一个哪一个函数最早执行完成返回的哪一个结果。函数
resolve() - 和then的第一个参数同样,返回一个promise成功后调用方法。spa
reject() - 和then的第二个参数同样,返回一个promise失败后调用的方法。code
本案例中我使用定时器模拟ajax服务器异步请求。blog
function Fun(a, b, cb) { setTimeout(function () { cb(a + b) }, 1000) } Fun(1, 2 ,function (result) { console.log(result) }); console.log(5); // 此时会先输出5在输出3
在复杂一点的案例确定是回调套回调,这样作确定是没有错代码也会执行,可是逻辑上不是很清晰。ip
function Fun(a, b, cb) { setTimeout(function () { cb(a + b) }, 1000) } Fun(1, 2, function (result) { if (result > 1) { Fun(result, 2, function (result) { Fun(result, 3, function (result) { console.log('完成', result) }) }) } }); console.log(5); // 此时会先输出5在输出 完成 8
function Fun(a, b) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(a + b) }, 1000) }) } Fun(1, 2) .then(function (result) { if (result > 1) { return Fun(result, 2) } }) .then(function (result) { if (result > 1) { return Fun(result, 3) } }).then(function (result) { console.log('完成', result) });
then的第一个参数是处理Promise成功后使用的方法,第二个参数是Promise处理失败后的方法,下面的案例我将会模拟错误。
若是Fun函数内传入的参数不是number类型,则触发then方法的错误处理函数,也就是第二个函数,固然第一个函数就不会执行了。
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } Fun(1, '1') .then(function (result) { if (result > 1) { return Fun(result, 2) } }, function (err) { //这个方法将会被执行,由于报错了么,很好理解吧 console.log(err ) }) .then(function (result) { console.log('第二个then'); //输出 第二个then 若是第一个then中的错误方法运用的稳当,对这里是不会有影响的,可是我并无作相应的处理 只是输出了err, result返回的是undefined,if中的方法也就不会执行了。 if (result > 1) { return Fun(result, 3) } });
then方法是从上向下运行,运行的中若是有发生错误的那么then方法就会在发生错误哪里中止运行,而且调用错误方法。注意:他与then的方法不一样,then的处理机制处理完会继续向下执行,而catch却不会,会跳过未执行的then直接进入catch
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } Fun(1, 1) .then(function (result) { if (result > 1) { console.log(1) // 1正常输出。 return Fun(result, '2') //这里2不是number类型. } }) .then(function (result) { // 因为上面传入的参数不是number类型,这里的then 就会调用错误处理,也就是说会执行catch方法。
console.log(2) // 不会执行 if (result > 1) { return Fun(result, 3) } }) .then(function (result) {
console.log(3) // 不会执行 console.log('完成', result) }) .catch( function (err) {//会被执行 no number console.log(err) } );
还有一种状况主动抛出异常被catch捕获
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } Fun(1, 1) .then(function (result) { if (result > 1) { if (result === 2) { throw new Error('我要抛出错误由于我任性' + result) //主动抛出异常 } console.log(1) 。 return Fun(result, 2) } } ) .then(function (result) { console.log(2) if (result > 1) { return Fun(result, 3) } }) .then(function (result) { console.log(3) console.log('完成', result) }) .catch(function (err) { // 我要抛出错误由于我任性2 console.log(err) });
若是then方法有第二个参数那么catch就不会执行,就会执行本身的第二个参数。能够将catch理解为接盘侠,若是then没有处理错误的方法,那么catch内的方法就会执行,若是同时没有then的第二个方法和catch那么就不会报错,由于压根就没有错误的处理机制那么就不会报错了。
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } Fun(1, '1') .then(function (result) { if (result > 1) { return Fun(result, 2) } }, function (err) { //执行 输出 no number +12 console.log(err + '12') }) .then(function (result) { console.log('第二个then'); // 执行输出 第二个then if (result > 1) { //这里不会执行由于没有result 由于result 是undefined 若是在第一个then的处理方法内处理的稳当这里就能够执行。 return Fun(result, 3) } }) .catch(function (err) { //这里不会执行,由于每一个then有本身的处理方式,因此catch就不会执行。 console.log(err + '我是catch的错误处理') });
这种方法在咱们平常的项目中很常见,可是这种代码使用起来过于繁琐,那么那有没有更好的方法呢?
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } let resultList = []; Fun(1, 2) .then(function (result) { resultList.push(result); return Fun(2, 3) }) .then(function (result) { resultList.push(result) console.log(resultList) });
all方法接收一个数组做为参数,数组内是方法,all会按照前后顺序返回一个执行后的数组。
function Fun(a, b) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, 1000) }) } var promise = Promise.all([Fun(1, 2), Fun(2, 3)]); promise.then(function (resule) { console.log(resule) //输出 3 5 });
race方法使用和all方法相似,可是返回结果不一样,all方法返回所有结果,race返回的是最早被执行完成那个函数的结果。注意:race接收参数的数组内,若是有一个方法报错,那么就不会返回结果。
function Fun(a, b ,time) { return new Promise(function (resolve, reject) { if (typeof a !== 'number' || typeof b !== 'number') { reject(new Error('no number')) } setTimeout(function () { resolve(a + b) }, time) }) } var promise = Promise.race([Fun(1, 2,1000), Fun(2, 3,200)]); //race 那个结果先被获得那么就会返回第一个获得的结果、可是若是总体有一个是错误的,那么就会抛出异常而不会获得结果。 promise.then(function (resule) { console.log(resule) //输出5 });
reject返回的事一个抛出异常错误的方法。因此then的第二个函数或者是catch会被执行。
var promise = Promise.reject("我要抛出错误"); promise.then(function (reason) { // 未被调用 console.log('reason') }, function (reason) { console.log(reason);//执行,由于reject就是抛出异常的方法。 });
resolve返回的事一个正常执行的方法,因此then的第一个函数会被执行。
var promise = Promise.resolve("我是会被执行的") promise.then(function (value) { console.log(value); // "我是会被执行的" }, function (value) { // 不会被调用 console.log(value) });