es6的学习笔记(三)
promise
promise,按照我的理解来说,是一种异步回调更优雅的写法
An alternative to callbacks and events
fetch(‘/items’)类似于ajax中的get,不过返回值是一个promise.
fetch('/items').then(
//do something
()=>console.log('hello')//此处加;是会报错的,一句话的箭头函数不应该有分号
)
//写法一
const p = fetch('/items')
p.then(res => {
// handle response
})
p.catch(error => {
// handle error
})
//写法二
const p = fetch('/items')
p.then(
res => {
// handle response
},
err => {
// handle error
}
) //上述两种写法是等价的
then和catch函数分别处理p的正确和错误。.then和.catch的返回值均是一个Promise,所以它的级联(chaining)变得很简单。
p.then(null, error => {
// handle error
})//此写法等价于p.catch(error=>{})
promise的创建方法
- 使用new Promise创建。Promise本质上是一个对象,可以使用New字符进行创建
new Promise(function(resolve,reject){
setTimeout(function(){
if(Math.random()>0.5)
resolve('random success');
else
reject(new Error('failed'));
},1000);
}).then(data=>console.log(data),err=>console.log(err));
- 也可以使用Promise.resolve和.reject直接创建,这种形式的Promise会直接执行。
Promise.resolve({result:'false'}).then((data)=>console.log(data.result))//这种形式的Promise会立即执行,结束后执行then里面的函数
then,catch函数的返回值
在一个then或者catch中,函数可以返回一个数值,抛出一个err,或者返回一个thenable的对象。
不论resolve的返回值是什么,均会执行下一个then函数,因为使用了resole),而reject的返回值不论是什么,都会执行catch,而then和catch是根据其返回值(reaction)来决定下一步执行then还是catch函数。
- 当返回值是一个数值的时候:其返回值会作为下一个then函数的输入数据,不会触发catch函数。如下面的代码,第一个resolve的返回值是数值2
之后执行then,返回2*7=14,因为返回了一个数值,继续执行下面的then,一直到最后,输出x=11。
Promise
.resolve(2)
.then(x => x * 7)
.then(x => x - 3)
.then(x => console.log(x))
// <- 11
- 当返回值是一个Promise的对象的时候,会等待其中的resolve或者reject函数执行。
Promise
.resolve(2)
.then(x => new Promise(function (resolve) {
setTimeout(() => resolve(x * 1000), x * 1000)
}))
.then(x => console.log(x))
// <- 2000
上述函数的第二个返回值是是一个promise对象,2s之后会执行resolve函数,返回值是2000,所以继续执行then,输出2000.
- 返回值(英文是reaction,类似于一个动作的反应,我感觉转换成程序语言,就是返回值的意思)是一个err,就会执行catch函数,而then函数不会被执行。
Promise.resolve(new Error('failed'))
.then(()=>{throw new Error('failed')})
.then(null,data=>console.log(data));
关于then,catch,resolve,reject的一些实例解释
//实例1,通过new新建Promise,在resolver中,执行reject函数并reaction一个错误,
//所以接下来会执行catch函数,data=上一步中的返回值(reaction)
//也就是new Error('oops')
new Promise((resolve, reject) => reject(new Error('oops')))
.catch(err => console.error(err))
//这段代码实现了和实例1一样的功能,也就是说,在resolver中执行throw,
//抛出一个错误,也会导致程序直接执行接下来的catch函数,与reject('返回值')的效果相同
new Promise((resolve, reject) => { throw new Error('oops'); })
.catch(err => console.error(err))
//这段代码在then函数中抛出了一个错误,所以会在下一步执行catch函数
Promise
.resolve(2)
.then(x => { throw new Error('failed'); })
.catch(err => console.error(err))
promise.all和race
The Promise.all method takes an array of promises and returns a single promise p. When all promises passed to Promise.all are fulfilled, p becomes fulfilled as well with an array of results sorted according to the provided promises. If a single promise becomes rejected, p settles with its rejection reason immediately.
promise.all的参数是一系列的promise数组,返回值是一个promise,当所有的promise完成了,然后他们的返回值会存储在一个数组中,顺序就是放入promise.all中的顺序,相反,如果其中一个错误,p就会立刻返回错误。
Promise
.all([
Promise.resolve(12),
Promise.resolve(10),
])
.then(products => console.log(products[0], products[1]))
这样的好处就是可以在好几个promise完成之后再一同处理数据。
所以,promise.all的输出值有三种情况:
- 输出里面promise的返回值
- 输出一个单独的错误
- 停留在pending的状态,因为其中有至少一个没有执行。
promise.race与all很相似,只是第一个结束的promise会直接输出,也就是说,返回值就是第一个promise完成的返回值,如果出错,也是返回第一个错误,之后的不会执行。所以叫race
Promise
.race([
new Promise(resolve => setTimeout(() => resolve(1), 1000)),
new Promise(resolve => setTimeout(() => resolve(2), 2000))
])
.then(result => console.log(result))
// <- 1
**补充:容易误会的一点,Promise.then.catch中的then,catch都是对上一个promise的处理,与Promise(f1,f2),f1就是then,f2就是catch,这两者是等价的。