美文网首页
再看Promise

再看Promise

作者: 钢笔先生 | 来源:发表于2019-11-28 02:08 被阅读0次

    Time: 2019-08-21

    回调函数

    是一种事件机制,某种事件完成后,会触发相应的回调函数。

    Promise是什么

    这是一种对异步回调函数的替代方式。Promise是一种对象。

    用回调的方式写loadJSON函数是下面这样:

    loadJSON(url, callback)
    

    其中callback函数还可以继续带上其他的回调函数,如此多个,称之为回调地狱。

    换成Promise的写法是:

    let promise = fetch(url);
    

    fetch函数会返回一个Promise对象,一旦得到Promise对象,我们就可以进而做很多事情。

    Promise对象的几种状态

    • pending
    • fulfilled/resolved
    • rejected

    我们可以检查Promise对象的状态,可以多次检查这个状态。和事件相比,错过了事件监听就是错过了,但是Promise正如名称讲到的一样,是一种承诺,状态是确定的。其中,Promise对象的状态会有两种流转方式:

    • pending -> fulfilled/resolved
    • pending -> rejected

    且状态切换之后是不可逆的。

    Q: 如何触发Promise对象的状态切换?

    两大函数

    • .then(),当对象的状态是fulfilled/resolved时
    • .catch(),当对象的状态是rejected时

    Promise对象是如何构建起来的?

    两种方式:

    • 主动构建
    • 使用某种函数后会返回这个对象,如fetch

    下面是个例子:

    let url = 'http://defi.sher.vip/company/listBlacklist'
    
    const gotData = (data) => {
        console.log("获取数据结果:", data) // 获取的是一个Response对象,需要解析这个对象
    }
    const gotError = (error) => {
        console.log(error)
    }
    let promise = fetch(url)
    
    promise.then(gotData)
    promise.catch(gotError)
    

    这样做打印出来是个Response对象,但还没有真的获取到我们需要的数据。

    在此之前,我们先看如何写成标准的写法:

    fetch(url)
        .then(
            data => {
                console.log("获取数据结果:", data)
            })
        .catch(
            err => {
                console.log("错误信息:", err)
            }
        )
    

    使用链式调用和箭头函数来减少代码量。

    可以再简化:

    fetch(url)
        .then( data => console.log("获取数据结果:", data))
        .catch( err => console.log("错误信息:", err))
    

    这三行代码表示的是,fetch(url)返回一个Promise对象,然后从pending进入到fulfilled/resolved状态后,执行.then中的代码,参数dataPromise返回的Response对象。

    pending进入到rejected状态时,执行.catch中的代码,参数err表示返回的错误。

    现在问题来了,如何取出真实的数据?进入到关于fetch函数的funny的部分了。

    开始以为data.json()就可以拿到数据了,其实呢,还是一个Promise对象。

    也就是需要再次.then()拿出需要的数据。

    一种天真但错误的写法:

    const res = await fetch(url).then(
                response => response.json()
            ).then(
                json
            )
    

    这会告诉我们json未定义,也就是then中接收的是函数,不管是普通函数还是箭头函数都可以。

    注意response => response.json() 是简单写法,实际上是return response.json(),返回的是Promise对象。

    屏幕快照 2019-08-22 下午8.54.58.png

    可以简化为:

    屏幕快照 2019-08-22 下午9.01.17.png

    其中在第二个then后的return fetch(...)很重要。

    手动构建Promise对象

    function delay(time)  {
    
    return new Promise((resolve, reject) => {
          // 可以加一些判断条件
          if (isNaN(time)) {
            reject()
          }
          setTimeout(resolve, time)
      })
    
    delay(1000).then(() => console.log("Hello"))
    }
    

    这样调用delay函数会返回一个Promise对象,并且成功后执行打印函数,相当于用自定义的箭头函数代替了resolve函数。

    Promise.all

    async && await

    参考

    https://youtu.be/QO4NXhWo_NM

    相关文章

      网友评论

          本文标题:再看Promise

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