一、同步模式与异步模式

同步模式:
代码执行顺序与编写顺序一致,一旦某行代码过长,就会延迟后面的任务
异步模式:
不会等待这个任务的结束再去下一个任务,一般通过回调函数的方式定义后续逻辑,代码执行顺序相对较跳跃
image.png

回调函数是所有异步编程方案的根基

二、事件循环与消息队列

image.png

三、promise

  1. const promise = new Promise(function (resolve, reject) {
  2. // resolve(100) // 承诺达成
  3. reject(new Error('promise rejected')) // 承诺失败
  4. })
  5. promise.then(function (value) {
  6. console.log('resolved', value)
  7. }, function (error) {
  8. console.log('rejected', error)
  9. })
  10. console.log('end') // 先打印出end,再打印Error
  11. -----------------------
  12. const p1 = new Promise((resolve, reject) => {
  13. setTimeout(() => {
  14. resolve(1)
  15. }, 100);
  16. })
  17. const p2 = Promise.resolve(2)
  18. const p3 = Promise.reject(3)
  19. p1.then(value => {console.log(value)})
  20. p2.then(value => {console.log(value)})
  21. p3.catch(reason => {console.log(reason)})
  22. all [promises] 全部完成
  23. Promise.all([promise1, promise2, promise3]).then((values) => {
  24. console.log(values);
  25. });
  26. race [promises] 一个完成
  27. Promise.race([promise1, promise2]).then((value) => {
  28. console.log(value);
  29. });

finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。

  1. p.finally(function() {
  2. // 返回状态为(resolved 或 rejected)
  3. });

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 () {
    1. if (this.status === 200) {
    2. resolve(this.response)
    3. } else {
    4. reject(new Error(this.statusText))
    5. }
    } xhr.send() }) }

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) })

  1. <a name="ura5t"></a>
  2. ## catch
  3. - 用 catch 注册失败回调是更常见的
  4. - 同时注册的 onRejected 只是给当前 Promise 对象注册的失败回调,它只能捕获到当前 Promise 对象的异常
  5. - Promise 链条上的任何一个异常都会被一直向后传递,直至被捕获,catch相当于给整个 Promise 链条注册失败回调
  6. 如何中断promise链?<br />在回调函数中返回一个pendding状态的promise对象
  7. ```javascript
  8. // 全局捕获 Promise 异常,类似于 window.onerror
  9. window.addEventListener('unhandledrejection', event => {
  10. const { reason, promise } = event
  11. console.log(reason, promise)
  12. // reason => Promise 失败原因,一般是一个错误对象
  13. // promise => 出现异常的 Promise 对象
  14. event.preventDefault()
  15. }, false)
  16. // Node.js 中使用以下方式
  17. // process.on('unhandledRejection', (reason, promise) => {
  18. // console.log(reason, promise)
  19. // // reason => Promise 失败原因,一般是一个错误对象
  20. // // promise => 出现异常的 Promise 对象
  21. // })

四、generator,Async/Await

  1. // 生成器函数回顾
  2. function * foo () {
  3. console.log('start')
  4. try {
  5. const res = yield 'foo'
  6. console.log(res)
  7. } catch (e) {
  8. console.log(e)
  9. }
  10. }
  11. const generator = foo()
  12. const result = generator.next()
  13. console.log(result)
  14. // generator.next('bar')
  15. generator.throw(new Error('Generator error'))
  1. function * main () {
  2. try {
  3. const users = yield ajax('/api/users.json')
  4. console.log(users)
  5. const posts = yield ajax('/api/posts.json')
  6. console.log(posts)
  7. const urls = yield ajax('/api/urls11.json')
  8. console.log(urls)
  9. } catch (e) {
  10. console.log(e)
  11. }
  12. }
  13. function co (generator) {
  14. const g = generator()
  15. function handleResult (result) {
  16. if (result.done) return // 生成器函数结束
  17. result.value.then(data => {
  18. handleResult(g.next(data))
  19. }, error => {
  20. g.throw(error)
  21. })
  22. }
  23. handleResult(g.next())
  24. }
  25. co(main)
  1. async function main () {
  2. try {
  3. const users = await ajax('/api/users.json')
  4. console.log(users)
  5. const posts = await ajax('/api/posts.json')
  6. console.log(posts)
  7. const urls = await ajax('/api/urls.json')
  8. console.log(urls)
  9. } catch (e) {
  10. console.log(e)
  11. }
  12. }
  13. const promise = main()
  14. promise.then(() => {
  15. console.log('all completed')
  16. })