一、同步模式与异步模式
同步模式:
代码执行顺序与编写顺序一致,一旦某行代码过长,就会延迟后面的任务
异步模式:
不会等待这个任务的结束再去下一个任务,一般通过回调函数的方式定义后续逻辑,代码执行顺序相对较跳跃
回调函数是所有异步编程方案的根基
二、事件循环与消息队列
三、promise
const promise = new Promise(function (resolve, reject) {// resolve(100) // 承诺达成reject(new Error('promise rejected')) // 承诺失败})promise.then(function (value) {console.log('resolved', value)}, function (error) {console.log('rejected', error)})console.log('end') // 先打印出end,再打印Error-----------------------const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(1)}, 100);})const p2 = Promise.resolve(2)const p3 = Promise.reject(3)p1.then(value => {console.log(value)})p2.then(value => {console.log(value)})p3.catch(reason => {console.log(reason)})all [promises] 全部完成Promise.all([promise1, promise2, promise3]).then((values) => {console.log(values);});race [promises] 一个完成Promise.race([promise1, promise2]).then((value) => {console.log(value);});
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
p.finally(function() {// 返回状态为(resolved 或 rejected)});
then链式调用
- 每一个then方法实际上,都是在为上一个then返回的promise对象添加状态明确过后的回调
- promise对象的then方法会返回一个新的promise对象
- 上一个then方法中回调的返回值会作为下一个then方法回调的参数
- 若回调中返回的是promise,下一个then的回调会等待它的结束
```javascript
function ajax (url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open(‘GET’, url)
xhr.responseType = ‘json’
xhr.onload = function () {
} xhr.send() }) }if (this.status === 200) {resolve(this.response)} else {reject(new Error(this.statusText))}
ajax(‘/api/users.json’) .then(function (value) { console.log(1111) return ajax(‘/api/urls.json’) }) // => Promise .then(function (value) { console.log(2222) console.log(value) return ajax(‘/api/urls.json’) }) // => Promise .then(function (value) { console.log(3333) return ajax(‘/api/urls.json’) }) // => Promise .then(function (value) { console.log(4444) return ‘foo’ }) // => Promise .then(function (value) { console.log(5555) console.log(value) })
<a name="ura5t"></a>## catch- 用 catch 注册失败回调是更常见的- 同时注册的 onRejected 只是给当前 Promise 对象注册的失败回调,它只能捕获到当前 Promise 对象的异常- Promise 链条上的任何一个异常都会被一直向后传递,直至被捕获,catch相当于给整个 Promise 链条注册失败回调如何中断promise链?<br />在回调函数中返回一个pendding状态的promise对象```javascript// 全局捕获 Promise 异常,类似于 window.onerrorwindow.addEventListener('unhandledrejection', event => {const { reason, promise } = eventconsole.log(reason, promise)// reason => Promise 失败原因,一般是一个错误对象// promise => 出现异常的 Promise 对象event.preventDefault()}, false)// Node.js 中使用以下方式// process.on('unhandledRejection', (reason, promise) => {// console.log(reason, promise)// // reason => Promise 失败原因,一般是一个错误对象// // promise => 出现异常的 Promise 对象// })
四、generator,Async/Await
// 生成器函数回顾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'))
function * main () {try {const users = yield ajax('/api/users.json')console.log(users)const posts = yield ajax('/api/posts.json')console.log(posts)const urls = yield ajax('/api/urls11.json')console.log(urls)} catch (e) {console.log(e)}}function co (generator) {const g = generator()function handleResult (result) {if (result.done) return // 生成器函数结束result.value.then(data => {handleResult(g.next(data))}, error => {g.throw(error)})}handleResult(g.next())}co(main)
async function main () {try {const users = await ajax('/api/users.json')console.log(users)const posts = await ajax('/api/posts.json')console.log(posts)const urls = await ajax('/api/urls.json')console.log(urls)} catch (e) {console.log(e)}}const promise = main()promise.then(() => {console.log('all completed')})
