/**
* Promise 特点
* 三种状态 Pending(进行中) Resolved(已完成) Rejected(已失败)
* 一旦状态改变 就不会再变 任何时候都可以得到这个结果 Promise对象的状态改变 有2种
可能 从Pending -> Resolved 和 Pending -> Rejected 改变后会一直保持这个结果
对Promise再添加回调 也会立即得到这个结果
*/
let isTrue = 1
// 实例 Promise (resolve, reject)
let promise = new Promise((resolve, reject) => {
if (isTrue) {
// 成功后调用 只能传递一个参数
resolve(value)
} else {
// 失败后调用 只能传递一个参数
reject(error)
}
})
promise.then(value => {
// 触发 resolve 调用该方法
}, (error) => {
// 触发 reject 调用该方法
})
let timeout = ms => {
// 创建 promise 对象
return new Promise((resolve, reject) => {
// 触发resolve方法
setTimeout(resolve, ms, 'done')
})
}
// resolve 方法触发第一个回调函数
timeout(1000).then(value => log(value))
let promise = new Promise((resolve, reject) => {
log('Promise')
resolve()
})
// then 指定的回调函数 将在当前脚本所有同步任务执行完才会执行
// 输出 Promise
// 输出 我在then回调前执行了
// 输出 Resolved
// 输出 我也执行了
promise.then(() => log('Resolved'))
log('我在then回调前执行了')
// setTimeout 不是同步任务 所以最后输出
setTimeout(() => log('我也执行了'), 1000)
let loadImage = url => {
// 实例化 promise
return new Promise((resolve, reject) => {
let image = new Image()
// 成功触发 resolve
image.onload = () => resolve(image)
// 失败触发 reject
image.onerror = () => reject('error')
image.src = 'http://wow2004.com/data/qq.jpg'
})
}
// resolve 后的调用第一个then函数
// reject 后调用第二个then函数
loadImage()
.then(value => log(value))
.then(error => log(error))
let url = 'http://www.wow2004.com/1.php'
let getData = url => {
return new Promise( (resolve, reject) => {
$.ajax({
url,
dataType: 'jsonp'
}).done(data => {
// 成功调用 resolve
resolve(data)
}).fail(data => {
// 失败调用 reject
reject('error')
})
})
}
getData(url)
.then(data => log(data))
.then(error => log(error))
/**
* resolve 接收 promise实例 作为参数 (只有resolve 可以接收promise作为参数)
p1和p2都是Promise的实例 但是p2的resolve方法将p1作为参数 即一个异步操作的结果
是返回另一个异步操作
这时p1的状态就会传递给p2 p1的状态决定了p2的状态 如果p1的状态是Pending 那么p2
的回调函数就会等待p1的状态改变 如果p1的状态已经是Resolved或者Rejected 那么p2
的回调函数将会立刻执行
*/
let p1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('错误'), 3000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => resolve(p1), 1000)
})
p2.then(
result => log(result),
error => log(error)
)
// then方法返回的是一个新的Promise实例 (不是原来那个Promise实例)
// 因此可以采用链式写法 即then方法后面再调用另一个then方法
// 第一个回调函数完成以后 会将返回结果作为参数 传入第二个回调函数
// 采用链式的then 可以指定一组按照次序调用的回调函数
let promise = new Promise((resolve, reject) => resolve(1))
let p = promise.then(
x => x + 1,
y => log(y)
).then(
x2 => log(x2),
y2 => log(y2)
)
let promise = new Promise((resolve, reject) => {
resolve('ok')
})
// 建议不要在then方法里定义 reject 状态的回调 总是使用catch
// 因为 catch 可以捕获then方法中的错误 也更接近同步的写法
promise
.then(x => log(x))
.catch(err => log(err))
// Promise 对象的错误具有冒泡性质 会一直向后传递 直到被捕获为止
let some = function () {
return new Promise((resolve, reject) => {
resolve(2)
})
}
some()
.then(x => log(x))
.then(() => { throw new Error('test') })
.catch(err => log(err))
// 分开写的promise 最多适用2层 ajax 嵌套 第三层没法写
let p1 = new Promise(resolve => {
setTimeout(() => {
resolve('p1')
}, 3000)
})
p1.then(value => {
log(value)
})
let p2 = new Promise(resolve => {
resolve(p1)
})
p2.then(
x => log('p2')
)
let p1 = new Promise(resolve => {
resolve('p1')
})
// 第一个then 会把返回结果作为参数 传入第二个回调函数
p1.then(v1 => {
return v1
}).then(v2 => {
// v2 == v1
log(v2)
})
let p1 = new Promise(resolve => {
setTimeout(() => resolve('第一个promise执行完成'), 3000)
})
// 前一个回调函数 有可能返回的还是一个Promise对象
// 这时后一个回调函数会等待该Promise对象的状态发生变化才会被调用
p1.then(v1 => {
log(v1)
// 这里必须添加一个return 以返回一个promise
return new Promise(resolve => {
setTimeout(() => resolve('等待执行完, 才会执行下一个then'), 3000)
})
}).then(v2 => {
log(v2)
return new Promise(resolve => {
setTimeout(() => resolve('最后一个promise'), 3000)
})
}).then(v3 => {
log(v3)
})
let p1 = new Promise(resolve => {
resolve('第一个promise执行完成')
})
// catch 会捕获所有then产生的错误
p1.then(v1 => {
return new Promise(resolve => {
resolve('等待执行完, 才会执行下一个then')
})
}).then(v2 => {
// 这里抛出错误
x + 1
}).catch(err => log(err))
/*
* Promise.all 用于将多个Promise实例 包装成一个新的Promise实例
* 包含两种状态
1) 只有p1 p2 p3的状态都变成已完成 Promise.all的状态才会变成已完成
此时p1 p2 p3的返回值组成一个数组 传递给p的回调函数
2) 只要p1 p2 p3之中有一个被rejected Promise.all的状态就变成 rejected
此时第一个被reject的实例的返回值 会传递给Promise.all 的回调函数
*/
let p1 = new Promise(resolve => {
setTimeout(() => resolve(1), 1000)
})
let p2 = new Promise(resolve => {
setTimeout(() => resolve(2), 2000)
})
let p3 = new Promise(resolve => {
setTimeout(() => resolve(3), 1000)
})
Promise.all([p1, p2, p3])
.then(v => log(v))
.catch(err => log(err))
// 如果没给then 返回值就是resolve返回的参数
// 如果给了then 返回值是then里return的值
let p1 = new Promise(resolve => {
setTimeout(() => resolve(1), 1000)
}).then(x => {
// 如果不给return Promise.all接收的返回值是空
return x
})
let p2 = new Promise(resolve => {
setTimeout(() => resolve(2), 3000)
})
Promise.all([p1, p2])
.then(v => log(v))
.catch(err => log(err))
// Promise.all 后面继续添加then
let p1 = new Promise(resolve => {
setTimeout(() => resolve(1), 1000)
})
let p2 = new Promise(resolve => {
setTimeout(() => resolve(2), 3000)
})
Promise.all([p1, p2])
.then(v => {
// 必须添加return 后面的then才会等待这个promise执行完 再执行
return new Promise(resolve => {
setTimeout(() => {
log('等待执行完')
resolve('我执行完了')
}, 3000)
})
})
.then(v => log('我开始执行'))
.catch(err => log(err))