Promise、跨域

1. 對(duì) Promise 的了解

(1)Promise的用途:為了解決命名不規(guī)范、回調(diào)地獄使得代碼復(fù)雜、難以進(jìn)行錯(cuò)誤處理等問題提出的規(guī)范,它可以規(guī)范回調(diào)的名字或順序、拒絕回調(diào)地獄、增加代碼可讀性,方便查找錯(cuò)誤。
(2)如何創(chuàng)建一個(gè)Promise

function fn(){
    return new Promise((resolve, reject)=>{
        成功時(shí)調(diào)用 resolve(data)
        失敗時(shí)調(diào)用 reject(reason)
    })
}

(3)如何使用 Promise.prototype.then
then() 方法返回一個(gè) Promise 。它最多需要有兩個(gè)參數(shù):Promise 的成功和失敗情況的回調(diào)函數(shù)。
例子是用Promis手寫的Ajax

ajax = (method, url, options) => {
      return new Promise((resolve, reject) => {
        const { success, fail } = options // 析構(gòu)賦值
        const request = new XMLHttpRequest()
        request.open(method, url)
        request.onreadystatechange = () => {
          if (request.readyState === 4) {
            // 成功就調(diào)用success,失敗就調(diào)用fail
            if (request.status < 400) {
              resolve.call(null, request.response)
            } else if (request.status >= 400) {
              reject.call(null, request, request.status)
            }
          }
        }
        request.send()
      })
}
ajax("get", "/xxx")
      .then((response) => {},
      (request) => {})
// then 的都一個(gè)參數(shù)就是success,第二個(gè)參數(shù)就是fail。另:promise規(guī)定成功還是失敗都只傳一個(gè)參數(shù)
const promise1 = fn() // 得到 promise1 對(duì)象
fn().then(success, fail).then(success2, fail2).catch(fail3)
// 或者
// promise1.then(success, fail).then(success2, fail2).catch(fail3)
// 均可

(4)如何使用 Promise.all
Promise.all可以將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例。同時(shí),成功和失敗的返回值是不同的,成功的時(shí)候返回的是一個(gè)結(jié)果數(shù)組,失敗時(shí)返回最先被reject失敗狀態(tài)的值。
Promise.all([promise1, promise2])并行,等待所有 promise 成功。
如果都成功了,則 all 對(duì)應(yīng)的 promise 也成功;如果有一個(gè)失敗了,則 all 對(duì)應(yīng)的 promise 失敗。

let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
  resolve('success')
})

let p3 = Promse.reject('失敗')

Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失敗了,打出 '失敗'
})

需要特別注意的是,Promise.all獲得的成功結(jié)果的數(shù)組里面的數(shù)據(jù)順序和Promise.all接收到的數(shù)組順序是一致的,即p1的結(jié)果在前,即便p1的結(jié)果獲取的比p2要晚。這帶來了一個(gè)絕大的好處:在前端開發(fā)請(qǐng)求數(shù)據(jù)的過程中,偶爾會(huì)遇到發(fā)送多個(gè)請(qǐng)求并根據(jù)請(qǐng)求順序獲取和使用數(shù)據(jù)的場(chǎng)景,使用Promise.all毫無疑問可以解決這個(gè)問題。
(5)如何使用 Promise.race
顧名思義,Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])里面哪個(gè)結(jié)果獲得的快,就返回那個(gè)結(jié)果,不管結(jié)果本身是成功狀態(tài)還是失敗狀態(tài)。
Promise.race([promise1, promise2])返回一個(gè) promise,一旦數(shù)組中的某個(gè)promise解決或拒絕,返回的 promise就會(huì)解決或拒絕。

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  },1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('failed')
  }, 500)
})

Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)  // 打開的是 'failed'
})

適用場(chǎng)景例如多臺(tái)服務(wù)器部署了同樣的服務(wù)端代碼,可以在race 中寫上所有服務(wù)器中的查詢商品列表的接口地址,哪個(gè)服務(wù)器響應(yīng)快,就從哪個(gè)服務(wù)器拿數(shù)據(jù)。

2. 跨域

  1. 源 = 協(xié)議 + 域名 + 端口號(hào)。如果兩個(gè)url的協(xié)議、域名、端口號(hào)完全一致,那么這兩個(gè)url就是同源的。
    例如https://baidu.com 、 https://www.baidu.com就是是不同源的
  2. 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)施的安全限制。
  3. JSONP跨域
    我們?cè)诳缬驎r(shí)由于當(dāng)前瀏覽器不支持或某種原因無法使用CORS時(shí),我們必須使用另外一種方式來跨域。于是我們?cè)诋?dāng)前網(wǎng)站創(chuàng)建一個(gè)script標(biāo)簽去請(qǐng)求一個(gè)另一個(gè)網(wǎng)站的js,js里面會(huì)攜帶一些數(shù)據(jù),然后在我們的網(wǎng)站中調(diào)用一個(gè)全局函數(shù)并運(yùn)行,就可以獲得這些數(shù)據(jù)。
    優(yōu)點(diǎn):
    (1)兼容IE。
    (2)可以跨域
    缺點(diǎn):
    (1)由于他是script標(biāo)簽,所以他讀不到AJAX那么精確的狀態(tài),拿不到狀態(tài)碼和header
    (2)由于他是script標(biāo)簽,所以他只能發(fā)送get請(qǐng)求,不支持post
  4. CROS跨域
    CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是“跨域資源共享”,允許瀏覽器像跨院服務(wù)器發(fā)出 XMLHttpRequest 請(qǐng)求,克服了AJAX只能同源使用的限制。
    CORS跨域分為簡(jiǎn)單請(qǐng)求和復(fù)雜請(qǐng)求兩種。
    4.1 簡(jiǎn)單請(qǐng)求:顧名思義是相對(duì)簡(jiǎn)單的請(qǐng)求,滿足一下條件的請(qǐng)求被稱為簡(jiǎn)單請(qǐng)求。
  • 請(qǐng)求方法
    GET
    POST
    HEATD
  • 字段
    Accept
    Accept-Language
    Content-Language
    Content-Type
  • Content-Type 的值
    text/plain
    multipart/form-data
    application/x-www-form-urlencoded
  • 實(shí)現(xiàn)過程
    當(dāng)使用 XMLHttpRequest發(fā)送請(qǐng)求時(shí),瀏覽器發(fā)現(xiàn)該請(qǐng)求不符合同源策略,會(huì)自動(dòng)給該請(qǐng)求加一個(gè)請(qǐng)求頭:Origin,并將請(qǐng)求發(fā)送。服務(wù)器端收到請(qǐng)求后,如果確定接受請(qǐng)求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin: <origin> | *; 瀏覽器收到響應(yīng)后判斷該相應(yīng)頭中是否包含 Origin 的值,如果有則瀏覽器會(huì)處理響應(yīng),我們就可以拿到響應(yīng)數(shù)據(jù),如果不包含瀏覽器直接駁回,這時(shí)我們無法拿到響應(yīng)數(shù)據(jù)。
    整個(gè)CORS通信過程,都是瀏覽器自動(dòng)完成,不需要用戶參。
    實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天青石的票圈出鏡率最高的,莫過于張藝謀的新片終于定檔了。 一張滿溢著水墨風(fēng)的海報(bào)一次次的出現(xiàn)在票圈里,也就是老謀...
    青石電影閱讀 10,961評(píng)論 1 2
  • 一、jQuery簡(jiǎn)介 JQ是JS的一個(gè)優(yōu)秀的庫(kù),大型開發(fā)必備。在此,我想說的是,JQ里面很多函數(shù)使用和JS類似,所...
    Welkin_qing閱讀 12,900評(píng)論 1 6
  • 字符串 1.什么是字符串 使用單引號(hào)或者雙引號(hào)括起來的字符集就是字符串。 引號(hào)中單獨(dú)的符號(hào)、數(shù)字、字母等叫字符。 ...
    mango_2e17閱讀 7,816評(píng)論 1 7
  • 一場(chǎng)說走就走的旅行。 簡(jiǎn)單地整理幾件必備旅行用品,7.18日早上8.00準(zhǔn)時(shí)出發(fā)了,計(jì)劃一路南下然后繞西南一圈回恩...
    悠游魚閱讀 3,673評(píng)論 3 6
  • 原來看過一段話,第一厲害的人有能力沒脾氣,第二厲害的人有能力有脾氣,最差的是沒能力有脾氣的人。 以我最...
    涼風(fēng)豆豆閱讀 1,635評(píng)論 2 0

友情鏈接更多精彩內(nèi)容