成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

前端雜談: 如何實(shí)現(xiàn)一個(gè) Promise?

forsigner / 2589人閱讀

摘要:并在其中判斷當(dāng)前狀態(tài)。如果在異步調(diào)用完成之后才被調(diào)用方法,則我們無(wú)法把異步調(diào)用的結(jié)果傳遞給回調(diào)函數(shù)。我們對(duì)可能出現(xiàn)的異常進(jìn)行捕獲,并將異常傳遞給。該實(shí)現(xiàn)的功能較為簡(jiǎn)陋,僅實(shí)現(xiàn)了部分規(guī)范。

前端雜談: 如何實(shí)現(xiàn)一個(gè) Promise? 首先, 什么是 Promise?
A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

關(guān)鍵語(yǔ)句: Promise 是一個(gè)在將來(lái)某個(gè)時(shí)刻產(chǎn)生一個(gè)單一結(jié)果的對(duì)象.
通俗一點(diǎn)來(lái)說(shuō), Promise 代表了一個(gè)值, 但是這個(gè)值我們并不確定什么時(shí)候會(huì)被返回.

A promise is an object that may produce a single value some time in the future.
簡(jiǎn)單看看 Promise 的歷史

Promise 在 1980 年代被創(chuàng)建出來(lái) =>

在 1988 年正式得名: Promise =>

已經(jīng)有很多人了解到了 Promise, 但是人們還是堅(jiān)持使用 node.js 中提倡的以回調(diào)函數(shù)首個(gè)參數(shù)傳 error 對(duì)象的方式處理異步代碼. =>

Dojo 首次大規(guī)模的使用了 Promise , 相應(yīng)的 Promise/A 被提出用以規(guī)范 Promise 的實(shí)現(xiàn) =>

JQuery 開(kāi)始使用 Promise 并真正使 Promise 廣為人知 =>

JQuery 沒(méi)有實(shí)現(xiàn)部分 Promise 的功能, 這也導(dǎo)致了 Promie/A+ 標(biāo)準(zhǔn)的產(chǎn)生 =>

ES6 正式引入了 Promise,并且和已有的實(shí)現(xiàn)了 Promise/A 規(guī)范的 library 相兼容 =>

實(shí)現(xiàn) Promise 之前, 讓我們看看 Promise 有哪些規(guī)范

Promise 是一個(gè) thenable 對(duì)象, 也就是說(shuō) Promise 有一個(gè) .then() 方法

一個(gè) pending 狀態(tài)的 Promise 可以進(jìn)入 fulfilled 和 rejected 狀態(tài)

promise 一旦進(jìn)入 fulfilled 或 rejected 狀態(tài), 不可再改變其狀態(tài)

一旦 promise 改變了其狀態(tài), 它筆芯有一個(gè)值(這個(gè)值也可能是 undefined)

開(kāi)始實(shí)現(xiàn)一個(gè) Promise

首先, 讓我們看看一段最普通的異步代碼:

// 異步方法定義
var basicAsyncFunc = function(callback) {
  setTimeout(function() {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) {
      callback(null, randomNumber)
    } else {
      callback(new Error("bad luck..."))
    }
  }, 1000)
}

// 異步方法調(diào)用
basicAsyncFunc((err, result) => {
  if (err) {
    console.log(`the reason fail is: ${err}`)
    return
  }
  console.log(`success get result: ${result}`)
})

按照 Promise 的規(guī)范定義, 理想中 Promise 的調(diào)用方式為:

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {}

// Promise 形式的異步方法調(diào)用
promiseAsyncFunc.then(
  data => {
    console.log(`success get result: ${data}`)
  },
  err => {
    console.log(`the reason fail is: ${err}`)
  }
)

按照這個(gè)理想當(dāng)中的調(diào)用方式, 讓我們寫出第一版代碼.

第一版 Promise:能保存回調(diào)方法
// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var fulfillCallback
  var rejectCallback

  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfillCallback(randomNumber)
    else rejectCallback(randomNumber)
  }, 1000)
  return {
    then: function(_fulfillCallback, _rejectCallback) {
      fulfillCallback = _fulfillCallback
      rejectCallback = _rejectCallback
    }
  }
}

// Promise 形式的異步方法調(diào)用
promiseAsyncFunc().then(fulfillCallback, rejectCallback)

我們的思路是在 .then() 方法中, 將 fullfill 和 reject 結(jié)果的回調(diào)函數(shù)保存下來(lái), 然后在異步方法中調(diào)用. 因?yàn)槭钱惒秸{(diào)用, 根據(jù) event-loop 的原理, promiseAsyncFunc().then(fulfillCallback, rejectCallback) 傳入的 callback 在異步調(diào)用結(jié)束時(shí)一定是已經(jīng)賦值過(guò)了.

第二版 Promise:實(shí)構(gòu)造函數(shù)

當(dāng)前我們的實(shí)現(xiàn) Promise 中,異步邏輯代碼和 Promise 的代碼是雜糅在一起的,讓我們將其區(qū)分開(kāi):

var promiseAsyncFunc = function() {
  var fulfillCallback
  var rejectCallback

  return {
    fulfill: function(value) {
      if (fulfillCallback && typeof fulfillCallback === "function") {
        fulfillCallback(value)
      }
    },
    reject: function(err) {
      if (rejectCallback && typeof rejectCallback === "function") {
        rejectCallback(err)
      }
    },
    then: function(_fulfillCallback, _rejectCallback) {
      fulfillCallback = _fulfillCallback
      rejectCallback = _rejectCallback
    }
  }
}

let ownPromise = function(asyncCall) {
  let promise = promiseAsyncFunc()
  asyncCall(promise.fulfill, promise.reject)
  return promise
}

// Promise 形式的異步方法調(diào)用
ownPromise(function(fulfill, reject) {
  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfill(randomNumber)
    else reject(randomNumber)
  }, 1000)
})

我們新定義了一個(gè)方法 ownPromise() 用于創(chuàng)建 Promise,并在promiseAsyncFunc() 中暴露出 fulfillreject 接口方便異步代碼去調(diào)用。

這里有一個(gè)問(wèn)題,我們?cè)谡{(diào)用 ownPromise()后得到了 promise 實(shí)例,此時(shí)我們可以直接調(diào)用 fulfill()reject()這兩個(gè)方法,而理論上我們應(yīng)該只應(yīng)暴露 promise 的then()方法。所以我們利用閉包將這兩個(gè)方法隱藏:

var promiseAsyncFunc = function() {
  var fulfillCallback
  var rejectCallback

  return {
    fulfill: function(value) {
      if (fulfillCallback && typeof fulfillCallback === "function") {
        fulfillCallback(value)
      }
    },
    reject: function(err) {
      if (rejectCallback && typeof rejectCallback === "function") {
        rejectCallback(err)
      }
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        fulfillCallback = _fulfillCallback
        rejectCallback = _rejectCallback
      }
    }
  }
}

let ownPromise = function(asyncCall) {
  let defer = promiseAsyncFunc()
  asyncCall(defer.fulfill, defer.reject)
  return defer.promise
}

// Promise 形式的異步方法調(diào)用
ownPromise(function(fulfill, reject) {
  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfill(randomNumber)
    else reject(randomNumber)
  }, 1000)
})
第三版 Promise: 支持狀態(tài)管理

為了實(shí)現(xiàn)規(guī)范中對(duì)于 Promise 狀態(tài)變化的要求, 我們需要為 Promise 加入狀態(tài)管理, 這一步較為簡(jiǎn)單, 讓我們看代碼:

const PENDING = Symbol("pending")
const FULFILLED = Symbol("fulfilled")
const REJECTED = Symbol("rejected")

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback

  return {
    fulfill: function(value) {
      if (status !== PENDING) return
      if (typeof fulfillCallback === "function") {
        fulfillCallback(value)
        status = FULFILLED
      }
    },
    reject(error) {
      if (status !== PENDING) return
      if (typeof rejectCallback === "function") {
        rejectCallback(error)
        status = REJECTED
      }
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        fulfillCallback = _fulfillCallback
        rejectCallback = _rejectCallback
      }
    }
  }
}

let ownPromise = function(asyncCall) {
  let defer = promiseAsyncFunc()
  asyncCall(defer.fulfill, defer.reject)
  return defer.promise
}

// Promise 形式的異步方法調(diào)用
ownPromise(function(fulfill, reject) {
  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfill(randomNumber)
    else reject(randomNumber)
  }, 1000)
}).then(data => console.log(data), err => console.log(err))

這段代碼中我們用到了 Symbol 來(lái)表示狀態(tài)常量, 對(duì) Symbol 不了解的同學(xué)可以看這里

為了判斷 Promise 的狀態(tài), 我們加入了 fulfillreject 兩個(gè)方法。并在其中判斷 promise 當(dāng)前狀態(tài)。如果不是 pending 狀態(tài)則直接 return(因?yàn)?Promise 狀態(tài)只可能改變一次)。

現(xiàn)在我們的 promise 實(shí)現(xiàn)了對(duì)狀態(tài)控制的規(guī)范:

只允許改變一次狀態(tài)

只能從 pending => fulfilled 或 pending => rejected

但是我們的 Promise 有一個(gè)問(wèn)題: promise 的值沒(méi)有被保存下來(lái)。如果 promise 在異步調(diào)用完成之后才被調(diào)用 .then() 方法,則我們無(wú)法把異步調(diào)用的結(jié)果傳遞給回調(diào)函數(shù)。為此我們需要為 Promise 加一個(gè) value 字段:

第四版 Promise: 保存異步調(diào)用的結(jié)果

我們?yōu)?promise 加入 value 字段,用于保存 Promise 的執(zhí)行結(jié)果。

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback
  var value

  return {
    fulfill: function(_value) {
      if (status !== PENDING) return
      value = _value
      status = FULFILLED
      if (typeof fulfillCallback === "function") {
        fulfillCallback(value)
      }
    },
    reject(error) {
      if (status !== PENDING) return
      value = error
      status = REJECTED
      if (typeof rejectCallback === "function") {
        rejectCallback(error)
      }
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        fulfillCallback = _fulfillCallback
        rejectCallback = _rejectCallback
      }
    }
  }
}

這里我們又發(fā)現(xiàn)一個(gè)問(wèn)題,如果一個(gè) Promise 已經(jīng)是fulfillreject狀態(tài)。我們?cè)僬{(diào)用 then() 方法時(shí),傳入的回調(diào)方法永遠(yuǎn)不會(huì)被調(diào)用(因?yàn)?status 已經(jīng)不是 pending)。

所以我們需要在 then()方法中對(duì)其狀態(tài)進(jìn)行判斷:

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback
  var value

  return {
    fulfill: function(_value) {
      if (status !== PENDING) return
      value = _value
      status = FULFILLED
      if (typeof fulfillCallback === "function") {
        fulfillCallback(value)
      }
    },
    reject(error) {
      if (status !== PENDING) return
      value = error
      status = REJECTED
      if (typeof rejectCallback === "function") {
        rejectCallback(error)
      }
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        if (status === REJECTED) {
          _rejectCallback(value)
          return
        }
        if (status === FULFILLED) {
          _fulfillCallback(value)
          return
        }
        fulfillCallback = _fulfillCallback
        rejectCallback = _rejectCallback
      }
    }
  }
}
第五版 Promise: 支持鏈?zhǔn)秸{(diào)用

為了支持鏈?zhǔn)秸{(diào)用,.then() 方法的返回值必須是用 thenable (根據(jù) Promise/A+ 規(guī)范, .then() 方法的返回值需要是一個(gè)的 Promise)

為此我們加入一個(gè)工具方法 makeThenable()。如果傳入的 value 本身就有 then()方法,則直接返回 value。否則返回一個(gè)有 then()方法的對(duì)象。
在該對(duì)象的 then()方法中,我們根據(jù) promise 的狀態(tài),調(diào)用不同的回調(diào)方法生成新的 value。

function makeThenable(value, status){
  if(value && typeof value.then === "function"){
    return value
  }
  if(status === FULFILLED){
    return {
      then: function(fulfillCallback, rejectCallback){
        return makeThenable(fulfillCallback(value), FULFILLED)
      }
    }
  }
  if(status === REJECTED) {
    return {
      then: function(fulfillCallback, rejectCallback){
        return makeThenable(rejectCallback(value), FULFILLED)
      }
    }
  }
}

有了以上的 makeThenable()方法,我們可以在 promise 的fulfill(),reject()回將 value 設(shè)置為 thenable:

var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback
  var value

  return {
    fulfill: function(_value) {
      if (status !== PENDING) return
      value = makeThenable(_value, FULFILLED) // 保證當(dāng)前promise的value為 thenable
      status = FULFILLED
      if (typeof fulfillCallback === "function") {
        value.then(fulfillCallback)
      }
    },
    reject(error) {
      if (status !== PENDING) return
      value = makeThenable(error, REJECTED) 、、  // 保證當(dāng)前value為 thenable
      status = REJECTED
      if (typeof rejectCallback === "function") {
        value.then(null, rejectCallback)
      }
    },
    promise: {
      then: function(){}
    }
  }
}

接下來(lái)讓我們看 then()方法。為了返回一個(gè)新的 promise,我們首先得創(chuàng)建一個(gè)新的 promise。其次當(dāng)前 promise 在fulfill()reject()時(shí),應(yīng)該調(diào)用新的 promise 的fullfill()reject()方法。所以我們?cè)趯?fulfullCallbackrejectCallback賦值給當(dāng)前 promise 時(shí),將其包裝一下。代碼如下:

    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        let newPromiseAsyncFunc = promiseAsyncFunc()
        let fulfillFunc = function(value) {
          newPromiseAsyncFunc.fulfill(_fulfillCallback(value))
        }
        let rejectFunc = function(err) {
          newPromiseAsyncFunc.fulfill(_rejectCallback(err))
        }
        if (status === PENDING) {
          fulfillCallback = fulfillFunc
          rejectCallback = rejectFunc
        } else {
          value.then(fulfillFunc, rejectFunc)
        }
        return newPromiseAsyncFunc.promise
      }
    }

如此,我們變得到了一個(gè)可以鏈?zhǔn)秸{(diào)用的 promise。讓我們來(lái)測(cè)試一下:

const PENDING = Symbol("pending")
const FULFILLED = Symbol("fulfilled")
const REJECTED = Symbol("rejected")

function makeThenable(value, status) {
  if (value && typeof value.then === "function") {
    return value
  }
  if (status === FULFILLED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        return makeThenable(fulfillCallback(value), FULFILLED)
      }
    }
  }
  if (status === REJECTED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        return makeThenable(rejectCallback(value), FULFILLED)
      }
    }
  }
}

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback
  var value

  return {
    fulfill: function(_value) {
      if (status !== PENDING) return
      value = makeThenable(_value, FULFILLED)
      status = FULFILLED
      if (typeof fulfillCallback === "function") {
        value.then(fulfillCallback)
      }
    },
    reject(error) {
      if (status !== PENDING) return
      value = makeThenable(error, REJECTED)
      status = REJECTED
      if (typeof rejectCallback === "function") {
        value.then(null, rejectCallback)
      }
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        let newPromiseAsyncFunc = promiseAsyncFunc()
        let fulfillFunc = function(value) {
          newPromiseAsyncFunc.fulfill(_fulfillCallback(value))
        }
        let rejectFunc = function(err) {
          newPromiseAsyncFunc.fulfill(_rejectCallback(err))
        }
        if (status === PENDING) {
          fulfillCallback = fulfillFunc
          rejectCallback = rejectFunc
        } else {
          value.then(fulfillFunc, rejectFunc)
        }
        return newPromiseAsyncFunc.promise
      }
    }
  }
}

let ownPromise = function(asyncCall) {
  let defer = promiseAsyncFunc()
  asyncCall(defer.fulfill, defer.reject)
  return defer.promise
}

let testChainedPromise = ownPromise(function(fulfill, reject) {
  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfill(randomNumber)
    else reject(randomNumber)
  }, 1000)
})
  .then(
    data => {
      console.log(data)
      return "return value in then1 fulfill"
    },
    err => {
      console.log(err)
      return "return value in then1 reject"
    }
  )
  .then(
    data => {
      console.log(data)
      return "return value in then2 fulfill"
    },
    err => {
      console.log(err)
      return "return value in then2 reject"
    }
  )
  .then(
    data => {
      console.log(data)
    },
    err => {
      console.log(err)
    }
  )

/**
console output:

0.9931984611850693
return value in then1 fulfill
return value in then2 fulfill
*/
第六版 Promise: Error handling
這里我們只對(duì)異步調(diào)用fulfill 回調(diào)中拋出的 error 進(jìn)行處理。

首先是異步調(diào)用部分,我們將其 try catch 起來(lái),在發(fā)生異常時(shí)調(diào)用 reject 方法,并將異常作為參數(shù)傳入。

let ownPromise = function(asyncCall) {
  let defer = promiseAsyncFunc()
  try {
    asyncCall(defer.fulfill, defer.reject)
  } catch (e) {
    defer.reject(e)
  }
  return defer.promise
}

然后是 fulfill 中可能出現(xiàn)的異常。我們對(duì)fulfillCallback(value)可能出現(xiàn)的異常進(jìn)行捕獲,并將異常傳遞給rejectCallback。

function makeThenable(value, status) {
  if (value && typeof value.then === "function") {
    return value
  }
  if (status === FULFILLED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        try {
          let newValue = fulfillCallback(value)
          return makeThenable(newValue, FULFILLED)
        } catch (e) {
          return makeThenable(rejectCallback(e), FULFILLED)
        }
      }
    }
  }
  if (status === REJECTED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        return makeThenable(rejectCallback(value), FULFILLED)
      }
    }
  }
}

最后讓我們對(duì)完整的代碼進(jìn)行測(cè)試:

const PENDING = Symbol("pending")
const FULFILLED = Symbol("fulfilled")
const REJECTED = Symbol("rejected")

function makeThenable(value, status) {
  if (value && typeof value.then === "function") {
    return value
  }
  if (status === FULFILLED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        try {
          let newValue = fulfillCallback(value)
          return makeThenable(newValue, FULFILLED)
        } catch (e) {
          return makeThenable(rejectCallback(e), FULFILLED)
        }
      }
    }
  }
  if (status === REJECTED) {
    return {
      then: function(fulfillCallback, rejectCallback) {
        return makeThenable(rejectCallback(value), FULFILLED)
      }
    }
  }
}

// Promise 形式的異步方法定義
var promiseAsyncFunc = function() {
  var status = PENDING
  var fulfillCallback
  var rejectCallback
  var value

  return {
    fulfill: function(_value) {
      if (status !== PENDING) return
      value = makeThenable(_value, FULFILLED)
      status = FULFILLED
      if (typeof fulfillCallback === "function") {
        value.then(fulfillCallback)
      }
    },
    reject(error) {
      if (status !== PENDING) return
      value = makeThenable(error, REJECTED)
      if (typeof rejectCallback === "function") {
        value.then(null, rejectCallback)
      }
      status = REJECTED
    },
    promise: {
      then: function(_fulfillCallback, _rejectCallback) {
        let newPromiseAsyncFunc = promiseAsyncFunc()
        let fulfillFunc = function(value) {
          newPromiseAsyncFunc.fulfill(_fulfillCallback(value))
        }
        let rejectFunc = function(err) {
          newPromiseAsyncFunc.fulfill(_rejectCallback(err))
        }
        if (status === PENDING) {
          fulfillCallback = fulfillFunc
          rejectCallback = rejectFunc
        } else {
          value.then(fulfillFunc, rejectFunc)
        }
        return newPromiseAsyncFunc.promise
      }
    }
  }
}

let ownPromise = function(asyncCall) {
  let defer = promiseAsyncFunc()
  try {
    asyncCall(defer.fulfill, defer.reject)
  } catch (e) {
    defer.reject(e)
  }
  return defer.promise
}

let testChainedPromise = ownPromise(function(fulfill, reject) {
  throw Error("here is an error in asyncCall")
  setTimeout(() => {
    var randomNumber = Math.random()
    if (randomNumber > 0.5) fulfill(randomNumber)
    else reject(randomNumber)
  }, 1000)
})
  .then(
    data => {
      console.log(data)
      return "return value in then1 fulfill"
    },
    err => {
      console.log(err.message)
      return "return value in then1 reject"
    }
  )
  .then(
    data => {
      console.log(data)
      throw Error("here is an error in fulfill1")
      return "return value in then2 fulfill"
    },
    err => {
      console.log(err.message)
      return "return value in then2 reject"
    }
  )
  .then(
    data => {
      console.log(data)
    },
    err => {
      console.log(err.message)
    }
  )


// console out:
Error: here is an error in asyncCall
return value in then1 reject
Error: here is an error in fulfill1
return value in then2 reject
總結(jié)

以上就是我們對(duì)于 Promise 的一個(gè)簡(jiǎn)單的實(shí)現(xiàn),實(shí)現(xiàn)思路主要參考了 Q-A promise library for javascript。該實(shí)現(xiàn)的 Promise 功能較為簡(jiǎn)陋,僅實(shí)現(xiàn)了部分 api/規(guī)范。有任何意見(jiàn)和建議歡迎在評(píng)論區(qū)交流 ;)

進(jìn)一步閱讀 && 引用

對(duì)于 Promise 使用以及error handle 的講解:

https://medium.com/javascript...

Promise 實(shí)現(xiàn)庫(kù)之一: Q 對(duì)于 Promise 實(shí)現(xiàn)的講解:

https://github.com/kriskowal/...
想了解更多 前端 和 數(shù)據(jù)可視化 ?

這里是我的 前端、_D3.js_ 、 數(shù)據(jù)可視化 的 github 地址, 歡迎 star & fork

ssthouse-blog

如果覺(jué)得本文不錯(cuò)的話, 不妨點(diǎn)擊下面的鏈接關(guān)注一下 : )

github 主頁(yè)

知乎專欄

掘金

想直接聯(lián)系我 ?

郵箱: ssthouse@163.com

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/99993.html

相關(guān)文章

  • 2017-10-27 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選裝飾器場(chǎng)景實(shí)戰(zhàn)配置之后端渲染理解同步異步和事件循環(huán)編寫高性能注意點(diǎn)線性漸變實(shí)現(xiàn)虛線等簡(jiǎn)單實(shí)用圖形中文服務(wù)端渲染開(kāi)發(fā)指南個(gè)人文章系列之事件類型個(gè)人文章使用必記掘金簡(jiǎn)介掘金性能大亂斗前端雜談中簡(jiǎn)單的數(shù)據(jù)圖形化 2017-10-27 前端日?qǐng)?bào) 精選 JS 裝飾器(Decorator)場(chǎng)景實(shí)戰(zhàn)webpack配置之后端渲染JavaScript:理解同步、異步和事件循環(huán)編寫高性能js注...

    Jeffrrey 評(píng)論0 收藏0
  • 雜談前端Web通信

    摘要:作為開(kāi)發(fā)同學(xué)的小伙伴客戶端的瀏覽器,有點(diǎn)小調(diào)皮還做了一個(gè)同源策略的限制,當(dāng)我們的數(shù)據(jù)請(qǐng)求遇到不同源的情況下跨域,我們就得嘗試其它的通信方法,不能一條道走到黑。 showImg(https://segmentfault.com/img/bVburZO?w=600&h=450); Web2.0以來(lái),Ajax的出世,解決了傳統(tǒng)表單提交頁(yè)面跳轉(zhuǎn),閃爍白屏等問(wèn)題。使得Web頁(yè)面可以實(shí)現(xiàn)局部更新,...

    Betta 評(píng)論0 收藏0
  • 前端雜談: CSS 權(quán)重 (Specificity)

    摘要:前端雜談權(quán)重權(quán)重想必大家都聽(tīng)說(shuō)過(guò)一些簡(jiǎn)單的規(guī)則大部分人也都知道較長(zhǎng)的權(quán)重會(huì)大于較短的權(quán)重高于但是具體規(guī)范是什么瀏覽器是按照什么標(biāo)準(zhǔn)來(lái)判定不同選擇器的權(quán)重的呢讓我們來(lái)看一下官方文檔是怎么說(shuō)的第一個(gè)關(guān)鍵詞官方文檔中用特異性來(lái)表示一個(gè)和其元素的相 前端雜談: CSS 權(quán)重 (Specificity) css 權(quán)重想必大家都聽(tīng)說(shuō)過(guò), 一些簡(jiǎn)單的規(guī)則大部分人也都知道: 較長(zhǎng)的 css sele...

    SimonMa 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<