Promise

Promise 是什么

  1. 认识 Promise
    Promise 是异步操作的一种解决方案
  2. 什么时候使用 Promise
    Promise 一般用来解决层层嵌套的回调函数(回调地狱 callback hell)的问题

Promise 的基本用法

  1. 实例化构造函数生成实例对象
const p = new Promise(() => {});
  1. Promise 的三种状态
    Promise有3种状态,一开始是 pending(未完成),执行 resolve, 变成 fulfilled(resolve),已成功,执行 reject,变成 rejected,已失败
    Promise 的状态一旦变化,就不会再改变了
// pending -> fulfilled
resolve();
// pending -> rejected
reject();
  1. then 方法
p.then(() => {
	console.log('success');
}, () => {
	console.log('error');
});
  1. resolve 和 reject 函数的参数
const p = new Promise((resolve, reject) => {
	resolve({username: 'Tom'});
})
p.then((data) => {
	console.log(data);
}, (err) => {
	console.log(err);
})

then()

  1. 什么时候执行
    pending -> fulfilled 时,执行 then 的第一个回调函数
    pending -> rejected 时,执行 then 的第二个回调函数
  2. 执行后的返回值
    then 方法执行后返回一个新的 Promise 对象

catch()

  1. 有什么用
    catch 专门用来处理 rejected 状态
    catch 本质上是 then 的特例
then(null, err => {})
  1. 基本用法
new Promise((resolve, reject) => {
	reject('reason');
}).then(data => {
	console.log(data);
}).catch(err => {
	console.log(err);
});

catch() 可以捕获它前面的错误
一般总是建议, Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误

finally()

  1. 什么时候执行
    当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行
  2. 本质
    finally() 本质上是 then() 的特例

Promise.resolve() 和 Promise.reject()

  1. Promise.resolve()
    是成功状态 Promise 的一种简写形式
new Promise(resolve => resolve('foo'));
// 简写
Promise.resolve('foo');

参数
(1) 一般参数

Promise.resolve('foo').then(data => {
	console.log(data);
})

(2) Promise
当 Promise.resolve() 接收的是 Promise 对象时,直接返回这个 Promise 对象,什么都不做

const p1 = new Promise(resolve => {
	setTimeout(resolve, 1000, '我执行了');
	// 上面等同于
	// setTimeout(() => {
	// 		resolve('我执行了');
	// }, 1000);
});
Promise.resolve(p1).then(data => {
	console.log(data);
})
// 等价于
p1.then(data => {
	console.log(data);
})
console.log(Promise.resolve(p1) === p1);

当 resolve 函数接收的是 Promise 对象时,后面的 then 会根据传递的 Promise 对象的状态变化决定执行哪一个回调

new Promise(resolve => resolve(p1)).then(data => {
	console.log(data);
});

(3) 具有 then 方法的对象

  1. Promise.reject()
    失败状态 Promise 的一种简写形式
new Promise((resolve, reject) => {
	reject('reason');
});
// 等价于
Promise.reject('reason');

参数
不管什么参数,都会原封不动地向后传递,作为后续方法的参数

const p1 = new Promise(resolve => {
	setTimeout(resolve, 1000, '我执行了');
})
Promise.reject(p1).catch(err => console.log(err));

Promise.all()

  1. 有什么用
    Promise.all() 关注多个 Promise 对象的状态变化
    传入多个 Promise 实例, 包装成一个新的 Promise 实例返回
  2. 基本用法
const delay = ms => {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, '我执行了');
  });
}

const p1 = delay(1000).then(() => {
  console.log('p1 完成了');
  return 'p1';
})
const p2 = delay(2000).then(() => {
  console.log('p2 完成了');
  return 'p2';
  // return Promise.reject('err');
});
const p = Promise.all([p1,p2]);
p.then(
  data => {
    console.log(data);
  },
  err => {
    console.log(err);
  }
)

Promise.race()

Promise.race() 的状态取决于第一个完成的 Promise 实例对象,如果第一个完成的成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败

const racePromise = Promise.race([p1, p2]);
racePromise.then(	
	data => {
		console.log(data);
	},
	err => {
		console.log(err);
	}
);

Promise.allSettled()

Promise.allSettled() 的状态与传入的 Promise 状态无关,永远都是成功的,它只会忠实的记录下各个Promise 的表现

const allSettledPromise = Promise.allSettled([p1, p2]);
allSettledPromise.then(
	data => {
		console.log(data);
	}
);

Promise 的注意事项

  1. resolve 或 reject 函数执行后的代码
    推荐在调用 resolve 或 reject 函数的时候加上 return,不再执行它们后面的代码
new Promise((resolve, reject) => {
	return resolve(123);
	// return reject('reason');
});
  1. Promise.all/race/allSettled 的参数问题
    参数如果不是 Promise 数组,会将不是 Promise 的数组元素转变成 Promise 对象
Promise.all([1,2,3]).then(datas => {
	console.log(datas);
});
// 等价于
Promise.all([
	Promise.resolve(1),
	Promise.resolve(2),
	Promise.resolve(3)
]).then(datas => {
	console.log(datas);
});

不只是数组,任何可遍历的都可以作为参数
数组、字符串、Set、Map、arguments、NodeList

Promise.all(new Set([1, 2, 3])).then(data => console.log(data))
  1. Promise.all/race/allSettled 的错误处理
    错误既可以单独处理,也可以统一处理
    一旦被处理,就不会在其他地方再处理一遍
const delay = ms => {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'error');
  });
}

const p1 = delay(1000).then(() => {
  console.log('p1 完成了');
  return 'p1';
})
// 第一种情况
.catch(err => console.log(err));

const p2 = delay(2000).then(() => {
  console.log('p2 完成了');
  return 'p2';
  // return Promise.reject('err');
})
// 第一种情况
.catch(err => console.log(err));

const p = Promise.all([p1,p2]);
p.then(
  data => {
    console.log(data);
  }
)
// 第二种情况
.catch(err => console.log(err));

Promise 的应用

<body>
  <img id="img" src="//img1.mukewang.com/604ec1a30001d21b17920764.jpg" alt="">
  <script>
    const loadImageAsync = url => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = function () {
          resolve(img);
        }
        img.onerror = function () {
          reject(new Error(`Could not load image at ${url}`));
        }
        img.src = url;
      })
    }
    const imgDom = document.getElementById('img');
    loadImageAsync('//img3.mukewang.com/604587df000158fd17920764.jpg').then(img => {
      imgDom.src = img.src
    });
  </script>
</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值