var x = 10;
(
function fun() {
var y = 20;
console.log(x) // 10
}
)();
console.log(y) // 报错 y is not defined ----- var在函数内部定义,是局部变量,函数外无法读取
-------------------------------------
if (true) {
var z = 300;
}
console.log(z) // 300 // var在其他代码块中定义,是全局变量
let ani = 'animal'
let nam = 'name'
let newAr = {
ani // 变量名直接作为对象的属性名,等同于 ( ani: ani 即 ani: animal) 前者是字符串,后者ani是变量
nam,
[ani + nam] : 2000, // 中括号中写表达式,作为对象的属性名或方法名
getAge() { // 方法名简写,相当于 getAge: funciton() { console.log(this.animalname) }
console.log(this.animalname)
}
}
newAr.getAge();
console.log(newAr,'newAr')
pending状态 变为 fulfilled状态
和pending状态 变为 rejected状态
Promise:只要改变已经发生了,你再对promise对象添加回调函数,也会立即得到这个结果
event----: 如果改变发生了,你再去监听,得不到结果
es6规定,Promise对象 是一个构造函数,用来生成Promise实例
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
... 异步操作
resolve(value); // 异步操作的结果作为参数,传递出去
} else {
reject(error);
}
});
promise.then(function(value) {
// success
// 该回调函数在promise对象状态变为resolved时调用,参数是promise对象 resolved时,传出的值
}, function(error) {
// failure
});
很重要的一个例子
//很重要的一个例子
function timeout(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms, 'done');
});
}
timeout(100).then((value) => {
console.log(value);
});
上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。
过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。
promise新建后会立即执行
// promise新建后会立即执行
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve(); // 这里没有传参,作用是去触发.then中的回调函数
// resovle()函数的作用,是把promise实例对象的状态变为resolved, --------
// 在异步操作成功时调用,并将异步操作的结果作为参数传递出去
// 而当promise实例对象的状态变为 resolved时,就会触发 .then函数中的 回调函数 --------
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise // 注意执行顺序
// Hi!
// resolved
上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。
然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。
( 请求图片 ) https://blog.csdn.net/h1534589653/article/details/77528367
( Image对象 ) https://blog.csdn.net/baihuaxiu123/article/details/53091105
异步加载图片
componentDidMount() {
function loadImage(url) {
return new Promise((resolve, reject) => {
const image = new Image('400', '200') // 生成image实例对象,宽高
image.onload = () => {
resolve(image) // 加载成功时候,返回image对象
}
image.onerror = () => {
reject( new Error(`could not load image at ${url}`)) // 加载失败是报错
}
image.src = url // 请求的图片地址
})
}
loadImage('http://pic.7y7.com/201410/2014102458431393_600x0.jpg')
.then(res => {
console.log( res.src ) // 拿到image对象的src 属性
this.setState({
images: res
},() => {console.log(this.state.images)})
}, () => {
// rejected状态下的回掉函数
})
}
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1); // p2异步操作的结果返回 --> p1 异步操作
})
上面代码中,p1和p2都是 Promise 的实例,
但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
----------------------------------------------------
注意: 上面例子中
p1的状态决定了p2的状态
(1) 如果 p1 的状态是pending,那么 p2 的回调函数就会等待 p1 的状态改变
(2) 如果 p1 的状态是 fulfilled或者rejected,那么 p2 的回调函数将会立即执行
componentDidMount() {
let i = 0
setInterval(() => {
console.log(`经过了${++i}s`)
},1000)
const p1 = new Promise( (resolve,reject) => {
setTimeout(() => {
reject(new Error('fail'))
console.log('3s') // console.log语句仍然会执行,并且在reject()异步函数 前执行
},3000)
})
const p2 = new Promise( (resolve,reject) => {
setTimeout( () => {
return resolve(p1) // 一般都在这里加return,这样后面的代码就不会执行,防止意外!!
console.log('1s')
}, 1000 )
})
p2.then(res => console.log(res)) // 并没有执行
.catch(error => console.log(error))
// 注意: p2.then(res => console.log(....))并没有执行,因为p2的状态变成了p1的状态,是rejected
// p2.then(res => console.log(res,'fulfilled'), res => console.log(res,'rejected'))
// 实际执行的是上面的 第二个回调函数
}
解析:
(1) p1 是一个promise对象,3s后状态变为rejected
(2) p2 是一个promise对象,状态在 1s 后改变,但是P2的resolvef方法返回的是p1,p1是promise对象
导致p2的状态由p1决定,即 p1的状态传递给p2
(3) P2会等待P1的状态改变为 fulfilled或者reject,P1状态改变后,P2的回调函数会立刻执行 ( --!!!重要!!!-- )
( 所以1s的时候,.then方法并没有输出内容 )
(并且3s后,p2的状态不是fulfilled,而是 rejeced,即是p1的状态 )
(4) 又过了2s,p1的状态变为 rejected,导致触发 .catch 回调函数
promise实例有.then方法,是定义在原型对象 Promise.prototype 上的
采用链式的then,可以指定一组按照次序调用的回调函数。
componentDidMount() {
let i = 0
setInterval(() => {
console.log(`经过了${++i}s`)
},1000)
const lian1 = new Promise( (resolve,reject) => {
return setTimeout(() => {
resolve('2s的promise的fulfilled状态返回值')
},2000)
})
lian1
.then(res => console.log(res))
.then( res => {
return new Promise( (resolve,reject) => {
return setTimeout(() => {
return reject('3s的promise的rejected状态返回值')
},1000)
})
})
.then(res => console.log(res,'reject'), res => console.log(res, 'reject'))
}
// 经过了1s
// 经过了2s
// 2s的promise的fulfilled状态返回值
// 经过了3s
// 3s的promise的fulfilled状态返回值 reject
// 经过了4s
Promise.prototype.catch() 是 .then(null, rejection) 的别名,用于指定发生错误时的回调函数
如果catch()方法抛出错误后,后面有then()方法,会照常执行,后面有catch()方法,错误还会被再一次捕获
p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
// 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
例子
getJSON('/post/1.json')
.then(function(post) {
return getJSON(post.commentURL);
})
.then(function(comments) {
// some code
})
.catch(function(error) {
// 处理前面三个Promise产生的错误
});
上面代码中,一共有三个 Promise 对象:一个由getJSON产生,两个由then产生。
它们之中任何一个抛出的错误,都会被最后一个catch捕获。
promise.prototype.finally()方法用于指定不管promise对象最后的状态如何,都会执行的操作
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
上面代码中,不管promise最后的状态,在执行完then或catch指定的回调函数以后,
都会执行finally方法指定的回调函数。
Promise.all() 方法用于将多个promise实例,包装成一个新的promise实例
( 即Promise.all()实例子是rejected状态 )
自己定义了catch()方法,就不会触发Promise.all()实例的 catch() 方法
const p = Promise.all( [p1, p2, p3] );
上面代码中,promise.all()方法,接受一个数组作为参数,p1, p2, p3都是promise实例
promise.all() 方法的参数可以不是数组,但是必须具有 iterator 接口
p的状态由 p1, p2, p3决定,分两种情况
(1) 只有p1,p2,p3的状态都变为 fulfilled, p的状态才会变为 fulfilled
此时,p1,p2,p3的返回值组成一个数组,传递给p的回调函数
(2) 只要p1,p2,p3中有一个被 rejected,p的状态就变成rejected
此时,第一个被rejected的实例的返回值,会传给p的回调函数
例子
情况1:
// a,b,c都是promise实例对象
// 当a,b,c都是fulfilled状态时, p 才是fulfilled状态,才会触发then的resolved状态的回调函数
// p 的回调函数的参数,是a,b,c都变为resolved状态时的返回值组成的数组
componentDidMount() {
let a = new Promise((resolve, reject) => {
return resolve(1)
})
let b = new Promise((resolve,reject) => {
return resolve(2)
})
let c = new Promise((resolve,reject) => {
return resolve(3)
})
const p = Promise.all([a,b,c]) // a,b,c都是promise实例对象
p.then(res => console.log(res)) // 输出 [1, 2, 3]
}
情况2:
// a,b,c都是promise实例对象
// 当a,b,c中有一个是rejected状态时,p的状态就是rejected状态,
// p 的回调函数的参数,是最先被rejected的Promse实例的返回值
componentDidMount() {
let a = new Promise((resolve, reject) => {
// return resolve(1)
return reject(new Error('错误来自promise----a'))
})
let b = new Promise((resolve,reject) => {
// return resolve(2)
return reject(new Error('错误来自promise----b'))
})
let c = new Promise((resolve,reject) => {
return resolve(3)
})
const p = Promise.all([a,b,c]) // p是rejected时,p的回调函数的参数是最先rejected的实例返回值
p.then(res => console.log(res))
.catch(err => console.log(err)) // 输出 Error: 错误来自promise----a
}
特殊情况
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]
上面代码中,p1会resolved,p2首先会rejected,
但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。
该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,
因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。
Promise.race()方法的作用同样是将多个promise对象实例包装成新的promise实例
const p = Promise.race([ // Promise.race() 只要有一个参数状态改变,p的状态就是跟着改变
fetch('/resource-that-may-take-a-while'), // fetch返回的是promise对象
new Promise(function (resolve, reject) { // 5s后变为rejected状态
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
解析:
fetch在5s钟内请求成功,p变成fulfilled状态,触发p的then()方法
fetch在5s中内请求失败,p变为rejected状态,触发p的catch()方法
promise.resolve()可以将对象转换为promise对象
new Promise(resolve => resolve('foo'))
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
总结:
Promise.resolve()的参数无论是什么类型 ( 或者不带参数,或者参数本来就是一个promise对象,或者参数是一个thenable对象,或者参数是原始值,或者参数是普通对象 )本质上Promise.resolve()都会把参数转化为Promise对象,只是状态分情况而已,比如:如果参数是thenable对象,会立即执行thenable对象的then方法,状态当然后then方法中的函数决定,从而决定Promise.resolve()返回的promise对象的状态
Promise.resolve()方法的参数分为四种情况
componentDidMount() {
const foo = new Promise( (resolve, reject) => {
return resolve('foo是一个promise实例对象')
})
const p = Promise.resolve(foo) // Promise.resolve()的参数是一个promise实例
console.log( p );
// 输出: Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "foo是一个promise实例对象"}
}
什么是 thenable 对象 ?
let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
// 如果Promise.resolve()的参数是 thenable对象, Promise.resolve()方法会把thenable对象转化为promise对象
// 然后立刻执行thenable对象的then方法
componentDidMount() {
const thenable = { // thenable对象,里面有then方法
then: (resolve,reject) => resolve('这是thenable对象')
}
Promise.resolve(thenable) // 参数是thenable对象,立刻执行thenable对象的then方法
.then(res => console.log(res)) // thenable对象的的状态是fulfilled,输出其返回值
}
// 输出:这是thenable对象
componentDidMount() {
const str = 'abc'
const foo = Promise.resolve(str)
// 参数是原始类型的值,Promise.resolve()方法会返回一个promise对象,状态是resolved
foo.then(res => console.log(res)) // 所以该回调会执行
}
Promise.reject()方法返回一个promise实例对象,状态是rejected
const p = Promise.reject('出错了');
p.then(null, function (s) {
console.log(s)
});
// 出错了
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))
p.then(null, function (s) {
console.log(s)
});
// 出错了
const f = () => console.log('now'); // 函数f是一个同步事件
Promise.resolve().then(f); // 通过Promise.resolve()返回一个promise对象,状态是resolved,f变成异步
console.log('next');
// next 所以会先输出next,再输出now
// now
如何让同步函数同步执行,异步函数异步执行,并且让他们具有统一的api呢?
await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用.
componentDidMount() {
const funSync1 = () => console.log('我是同步函数1111111')
const funSync2 = () => console.log('我是同步函数2222222')
const funAsync = async () => { // async关键字,定义的函数是异步函数,返回promise对象
await funSync1()
}
funAsync().then(funSync2())
console.log('bbbb')
}
// 先把两个同步函数变成了异步,在异步函数中,先执行funSync1,后执行funSync2
// 使用async关键字后,会把同步包装成的异步函数,按同步方式执行
// 所以最后得到的输出顺序是:
// 我是同步函数1111111
// 我是同步函数2222222
// bbbb
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');
// now
// next
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now
// next
作者:省局到
链接:https://www.jianshu.com/p/4a937870511d
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。