const p1 = new Promise((resolve,reject)=>{
resolve('传入值') //就是这时的传入值,影响p1的状态
})
1、传入普通值,当前Promise状态是fulfilled。
2、传入new Promise() ,当前Promise的状态由新传入的Promise的状态决定。
const p1 = new Promise((res)=>{
res(new Promise((res,rej)=>{
rej('失败了')
}))
})
//p1 状态是rejected
3、传入thenable对象(对象实现了then方法),thenable方法会接收到resolve和reject两个方法(类似new Promise()),当前Promise的状态由执行哪个方法决定。
const p1 = new Promise((res)=>{
res({
then(res,rej){
rej('还是失败哦')
}
})
})
// p1 rejected状态
then会返回新的Promise,其状态由then的返回值决定,而then回调函数的返回值又会传给resolve(),所以与resolve()传入值的情况类似
1、then返回普通值或者不返回(也就是返回undefined),then状态为fulfilled。
2、then返回新的Promise,then状态由新的Promise决定。
3、then的回调报错,then状态为rejected。
4、then返回thenable对象,由对象的then方法决定。
由上能总结出:
1、then回调中有报错。
2、then返回失败的promise。
3、then返回thenable对象中,对象的then方法执行失败的方法。
返回fulfilled的Promise
返回rejected的Promise。无论reject传入什么,都是rejected状态的Promise,这与resolve不同。
返回Promise,传入一个可迭代的容器(可以是数组,可迭代对象iterator),容器会包含Promise实例,只有所有的Promise的状态都为fulfilled了,结果就会放在一个数组中;只要一个Promise是rejected的,就能在catch中接收到rejected的结果。
【通俗理解:小组所有成员都成功了就取所有成员的结果,有一个失败就取失败的结果】
Promise.all([p1,'aaa'])
//p1是promise实例,'aaa'字符串会被Promise.resolve()包裹
返回Promise,容器中所有Promise都有结果了,无论成功与否,返回的Promise状态就是成功,Promise的结果数体现在数组中。
【取所有小组成员的结果,无论成功还是失败】
返回Promise,容器中Promise的状态谁最先发生变化,该Promise的状态就与他一致,无论失败与成功。
【取最先变化的结果,无论成功还是失败】
返回Promise,容器中的Promise谁最先成功,该Promise的状态就是成功。所有Promise失败则将所有失败结果放在数组中。
无论成功还是失败,最后都会执行finally,可以用于关闭加载动画。
iterator叫迭代器,是一个具体的对象,需要符合迭代器协议,即:该对象需要实现next方法,next方法返回一个对象,这个对象又包含value(本次迭代的值)和done属性(布尔,表示是否迭代完所有元素)。
下面代码演示对数组的迭代:迭代完,done就是true,可以省略
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true,value:undefined};
}
};
}
var it = makeIterator(['a', 'b']);
console.log(it.next().value); // 'a'
console.log(it.next().value); // 'b'
console.log(it.next().done); // true
可迭代对象也是一个对象,但是需要符合可迭代协议(注意不是迭代器的规范),可迭代协议:可迭代对象需要实现[Symbol.iterator]方法,而这个方法刚好返回迭代器。
下面演示将对象转为可迭代对象。可迭代对象就能用forof进行遍历了,forof的原理就是不断调用迭代器的next方法,知道done为true。
const obj = {
name: '哈哈',
age: 343
}
//将普通对象转为可迭代对象
function getIteratorObj(obj) {
return {
data: obj,
// 首先有Symbol.iterator方法,这个方法返回迭代器
[Symbol.iterator]: function() {
let index = 0
let dataArr = Object.values(this.data)
return { //迭代器是对象,有next方法
next: () => { //next方法返回有done和value属性的对象
if (index < dataArr.length) {
return {
doen: false,
value: dataArr[index++]
}
} else {
return {
done: true,
value: undefined
}
}
}
}
}
}
}
for (let value of getIteratorObj(obj)) {
console.log(value);
}
String、Array、Map 、Set、arguments对象、nodeList集合
forof、展开运算、解构赋值、Promise的静态方法、Set\Map等
生成器函数是一种特殊的函数,是一种新增的函数控制、使用的方案。(比如可以让我们函数执行一半时暂停,等会再执行)
生成器函数的返回值是生成器对象,这个生成器对象同时符合迭代器协议和可迭代对象协议,即生成器对象有next方法还有[Symbol.iterator]方法。
看下面的代码理解生成器对象符合迭代器协议和可迭代协议:
function* generator() {
yield 'Hello';
yield 'World';
}
let gen = generator();
console.log(gen.next()); // 输出 { value: 'Hello', done: false }
console.log(gen.next()); // 输出 { value: 'World', done: false }
console.log(gen.next()); // 输出 { value: undefined, done: true }
for (let value of generator()) {
console.log(value); // 输出 "Hello", "World"
}
function * foo(){
const yieldValue_1 = yield '第一次执行next'
console.log(yieldValue_1,'第二次next传进来的值');
yield '第二次执行next'
}
let a = foo()
console.log(a.next(),'first Value');// {value: '第一次执行next', done: false} //返回yield右边表达式的结果
console.log(a.next('传递value'),'second Value'); //上一次yield的返回值就是本次next传入的值
说明: 生成器对象.next(),执行到一个yield处,返回yield右边表达式的值。上一次yield的返回值就是本次next传入的值。
async/await就是基于Promise和生成器的语法糖