再看Promise

2019-11-28  本文已影响0人  钢笔先生

Time: 2019-08-21

回调函数

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

Promise是什么

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

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

loadJSON(url, callback)

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

换成Promise的写法是:

let promise = fetch(url);

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

Promise对象的几种状态

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

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

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

两大函数

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

两种方式:

下面是个例子:

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

上一篇下一篇

猜你喜欢

热点阅读