# JavaScript异步编程
# 内容概要:
同步模式与异步模式
事件循环与消息队列
异步编程的几种方式
Promise 异步方案、宏任务/微任务
Generator 异步方案、Async/ Await 语法糖
# promise 基本用法
const promise = new Promise((resolve, reject) => {
// 这里用于“兑现承诺”
// resolve(100) // 承诺达成
reject(new Error('promise rejected')) // 只能调用二者其一
})
// resolve 和 reject 只能调用其一
promise.then(value => {
console.log(value) // reslove 调用执行的方法
},error => {
console.log('rejected error ', error) // reject 调用执行的方法
})
console.log('end')
# promise常见误区
ajax('..../xxx')
.then(function(value) {
console.log(1111)
// return new Promise()
return ajax('.../aaa') // 这个执行完以后 自动执行下一个then 状态明确过后的回调
})
.then(function(value) {
console.log(2222)
return 'aaa'
})
.then(function(value) {
console.log(3333)
console.log(value) // aaa 如果上一个then没有 return 该值为 undefined
})
.then(function(value) {
console.log(4444)
})
.then(function(value) {
console.log(5555)
})
promise 的本质就是使用回调函数的定义异步任务结束后所需要执行的任务 +每一个then方法为上一个then方法返回的promise添加状态明确的回调
then 方法中可以返回一个全新的promise Promise 对象的 then 方法会返回一个全新的 Promise 注册回调
# 异常捕获
- onreject 方法捕获
ajax('../aaa') .then(function onFulfilled(value) { console.log('onfulfilled') }, function onreject(error) { console.log('onreject') }) // 给第一个promise指定的错误回调,只能捕获到上一个promise的错误 <!-- catch 捕获 --> ajax('../aa') .then(function onFulfilled(value) { console.log('onfulfilled') }) .catch(function onreject(error) { console.log('onreject') }) // 之前的第一个promise返回的错误,通过链式传递给它,也就是说catch捕获到的 不一定是上一个then的promise
# Promise 静态方法
Promise.resolve() 将一个静态值转换为一个promise对象
Promise.resolve('foo') // 返回一个返回值为 foo 的promise对象
Promise.resolve('foo')
.then(function (value) {
console.log(value) // foo
})
new Promise(function (reslove, reject) {
resolve('foo')
})
// 二者等价
// 如果传入的是一个 Promise 对象, Promise.resolve 方法原样返回
var promise = ajax('api/user.json')
var promise2 = Promise.resolve(promise)
console.log(promise === promise2) // true
如果传入的是带有一个跟 Promise 一样的 then 方法的对象,Promise.resolve会将这个对象作为 Promise 执行
Promise.resolve({ then: function (onFullfilled, onRejected) { onFullfilled('foo') } }) .then(function (value) { console.log(value) })Promise.reject 传入任何值,都会作为这个 Promise 失败的理由
Promise.reject(new Error('rejected')) .catch(function (error) { console.log(error) })
# promise 并行执行
var promise = Promise.all([
ajax('api/users.json'),
ajax('api/users.json')
])
promise.then(function(value) {
console.log(value) // value 是一个数组,数组中包含每个promise执行的结果
}).catch(function(error) {
console.log(error)
})
ajax('/api/urls.json')
.then(value => {
const urls = Object.values(value)
const tasks = urls.map(url => ajax(url))
return Promise.all(tasks)
})
.then(values => {
console.log(values)
})
# Promise.race 实现超时控制 以第一个异步结束为准
Promise.race([
request,
timeout
])
.then(value => {
console.log(value)
})
.catch(error => {
console.log(error)
})