1.同步模式
任务依次执行,当前任务执行完,才能执行下一个任务
2.异步模式
特点
- 不会等待这个任务的结束才开始下一个任务
- 开启过后就立即往后执行下一个任务(对耗时操作)
- 后续逻辑一般通过回调函数的方式定义
其他:如果没有这种模式的话,单线程的JS语言就无法同时处理大量耗时任务
console.log('global begin')
setTimeout(function timer1 () {
console.log('timer1 invoke')
}, 1800)
setTimeout(function timer2 () {
console.log('timer2 invoke')
setTimeout(function inner () {
console.log('inner invoke')
}, 1000)
}, 1000)
console.log('global end')
//global begin
//global end
//timer2 invoke
//timer1 invoke
//inner invoke
总体过程:
- JS线程某一时刻发起异步调用,然后执行本轮其他任务
- 此时异步线程单独执行异步任务,执行完任务过后,将任务的回调放入消息队列
- js主线程完成所有的任务过后,会依次执行消息队列中的任务
补充:
1.事件循环的作用:
- 监听调用栈和消息队列
- 一旦调用栈中所有的任务都结束,就会从消息队列中取出第一个回调函数
- 然后压入调用栈
2.同步和异步不是指写代码的方式,而是运行环境提供的API是以同步或异步模式的方式工作
3.回调函数
function foo (callback) {
setTimeout(function () {
callback()
}, 3000)
}
foo(function () {
console.log('这就是一个回调函数')
console.log('调用者定义这个函数,执行者执行这个函数')
console.log('其实就是调用者告诉执行者异步任务结束后应该做什么')
})
// 回调地狱,只是示例,不能运行
$.get('/url1', function (data1) {
$.get('/url2', data1, function (data2) {
$.get('/url3', data2, function (data3) {
$.get('/url4', data3, function (data4) {
$.get('/url5', data4, function (data5) {
$.get('/url6', data5, function (data6) {
$.get('/url7', data6, function (data7) {
// 略微夸张了一点点
})
})
})
})
})
})
})
4.Promise
1.promise的基本流程
2.基本代码
//1.创建promise对象(pending状态),
const p=new Promise((resolve,reject)=>{
//2.在执行器函数中启动异步任务
setTimeout(()=>{
const time=Data.now()
//3.根据结果做不同的处理
//3.1如果成功,调用resolve(),指定成功的value,状态变为resolved
if(time%2===1){
resolve('成功的值'+time)
}else{
//3.1如果失败,调用reject(),指定失败的reason,变为rejected状态
reject('失败的值'+time)
}
},2000)
})
//通过promise指定成功或失败的回调函数来获取成功的value或失败的reason
p.then(
value=>{ //成功的回调函数onResolved,得到成功的value
console.log('成功的value',value)
},
reason=>{ //失败的回调函数onRejected,得到失败的reason
console.log('失败的reason',reason)
}
)
3.API
-
Promise 构造函数: Promise (excutor) {} excutor 函数: 同步执行 (resolve, reject) => {} resolve 函数: 内部定义成功时我们调用的函数 value => {} reject 函数: 内部定义失败时我们调用的函数 reason => {} 说明: excutor 会在 Promise 内部立即同步回调,异步操作在执行器中执行
-
Promise.prototype.then 方法: (onResolved, onRejected) => {}
onResolved 函数: 成功的回调函数 (value) => {}
onRejected 函数: 失败的回调函数 (reason) => {}
说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调 返回一个新的 promise 对象
-
Promise.prototype.catch 方法: (onRejected) => {}
onRejected 函数: 失败的回调函数 (reason) => {}
-
Promise.resolve 方法: (value) => {}
value: 成功的数据或 promise 对象
说明: 返回一个成功/失败的 promise 对象
-
Promise.reject 方法: (reason) => {}
reason: 失败的原因
说明: 返回一个失败的 promise 对象
-
Promise.all 方法: (promises) => {}
promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
-
Promise.race 方法: (promises) => {}
promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的 结果状态
5.Generator
1.函数名称前面加一个星号表示它是一个生成器
2.调用生成器函数会产生一个生成器对象,生成器对象一开始处于暂定执行的状态,它与迭代器相似,生成器对象也实现了Iterator接口,因此具有next()方法,调用它可以让生成器开始或者恢复执行
3.next的返回值类似于迭代器,有一个done属性和value属性。函数体为空的生成器函数中间不会停留,调用一次next()就让生成器达到done:true
4.value属性是生成器函数的返回值,默认为undefined,可以通过生成器函数的返回值指定
5.yield关键字可以让生成器停止和开始执行。生成器函数在遇到yield关键字之前都会正常执行,遇到之后,会停止,函数作用域的状态会被保留。只有通过next()来恢复执行
6.throw()方法会在暂停的时候将一个提供的错误注入生成器对象,提前终止生成器
// 生成器函数回顾
function * foo () {
console.log('start')
try {
const res = yield 'foo'
console.log(res)
} catch (e) {
console.log(e)
}
}
const generator = foo()
const result = generator.next()
console.log(result)
// generator.next('bar')
generator.throw(new Error('Generator error'))
6.Async
- 使用
async / await, 搭配promise, 可以通过编写形似同步的代码来处理异步流程 await操作符用于等待一个Promise对象, 它只能在异步函数async function内部使用- 使用
async function可以定义一个 异步函数