美文网首页
JS异步方案

JS异步方案

作者: 洲行 | 来源:发表于2020-09-30 14:22 被阅读0次

    Promise

    出现目的,为了解决回调地狱
    promise的用法就不赘述了,提一下错误处理吧

    ajax('/api/users11.json')
      .then(function onFulfilled (value) {
         console.log('onFulfilled', value)
       }, function onRejected (error) {
         console.log('onRejected', error
       })
    
    // 使用 catch 注册失败回调是更常见的
    
     ajax('/api/users11.json')
       .then(function onFulfilled (value) {
         console.log('onFulfilled', value)
       })
       .catch(function onRejected (error) {
         console.log('onRejected', error)
       })
    

    then的第二个参数就是reject时执行函数
    在promise中手动调用reject()会打印“onRejected”,代码发生错误也会触发打印“onRejected”。
    然后catch = then的第二个参数(失败回调函数)
    他俩的区别是catch能抓到整个链路的错误,then中的错误处理函数只能抓到他之前的promise中的错误

    实现几个例子

    let promise = new Promise((resolve, reject) => {
        reject(2000)
    })
    promise
        .then((v)=>console.log('then1成功', v), (r)=>console.log('then1失败', r))
        .catch((e)=>console.log('catch1', e))
        .then((v)=>console.log('then2成功', v), (r)=>console.log('then2失败', r))
        .catch((e)=>console.log('catch2', e))
    // =>then1成功 1000
    // =>then2成功 undefined  因为then1中没有return v
    
    let promise = new Promise((resolve, reject) => {
        reject(2000)
    })
    promise
        .then((v)=>console.log('then1成功', v), (r)=>{console.log('then1失败', r); return r})
        .catch((e)=>console.log('catch1', e))
        .then((v)=>console.log('then2成功', v), (r)=>console.log('then2失败', r))
        .catch((e)=>console.log('catch2', e))
    // =>then1失败 2000
    // =>then2成功 2000
    // 可见错误处理一回后,后面的catch也不会走到
    // 错误处理函数结束后,后续继续走成功回调
    
    let promise = new Promise((resolve, reject) => {
        reject(2000)
    })
    promise
        .catch((e)=>console.log('catch0', e))
        .then((v)=>console.log('then1成功', v), (r)=>console.log('then1失败', r))
        .catch((e)=>console.log('catch2', e))
    // => catch0 2000
    // => then1成功 2000
    // 还是错误处理只处理过一回后,将不再走以后的错误处理
    // 除非后面又有新的错误
    

    Generator

    Promise的异步方案还是不够扁平化,所以出现了Generator生成器函数

    // Generator 配合 Promise 的异步方案
    
    function ajax (url) {
      return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest()
        xhr.open('GET', url)
        xhr.responseType = 'json'
        xhr.onload = () => {
          if (xhr.status === 200) {
            resolve(xhr.response)
          } else {
            reject(new Error(xhr.statusText))
          }
        }
        xhr.send()
      })
    }
    
    function * main () {  // *生成器函数
      try {
        const users = yield ajax('/api/users.json') // yield,暂停执行,等待生成器对象的next方法调用
        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 Await

    Async完全就是上面代码方案的语法糖,把*变成Async,yield变成await,并且不需要co函数了

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

    同步的方式写异步,舒服了。

    相关文章

      网友评论

          本文标题:JS异步方案

          本文链接:https://www.haomeiwen.com/subject/ilksuktx.html