中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Node.js怎么實現一個無侵入式緩存框架

發布時間:2021-04-13 17:39:04 來源:億速云 閱讀:154 作者:Leah 欄目:web開發

這篇文章將為大家詳細講解有關使用Node.js怎么實現一個無侵入式緩存框架,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

python 的flask.ext.cache 通過注解這樣對方法返回結果進行緩存:

@cache.cached(timeout=300, key_prefix='view_%s', unless=None)
def hello(name=None):
  print 'view hello called'
  return render_template('hello.html', name=name)

這類實現方式對業務邏輯沒有絲毫的侵入性,非常之優雅。

最近在做 Node.js 地項目,然而 js ES 7 之前都不支持注解,目前見到的緩存框架雖然在 API 設計上都很簡潔、很有想法。

可是痛點在于它們都是侵入式的,需要在業務邏輯代碼中插入緩存邏輯,這些方式很不優雅。

正題

今天花點時間研究下js有沒有辦法,以比較優雅地方法實現緩存。

我對緩存框架的訴求:

  • 不對原方法進行更改

  • 能實現對不同參數地緩存

  • 支持緩存時間

我了解到的 js 能力:

  1. 隱藏參數arguments可以獲取參數列表

  2. prototype 可用來重寫覆蓋原方法

可行性?

看了看 prototype 文檔

直覺告訴我看起來可行,以下是官方的說明:

當一個函數被調用時,調用的參數被保留在類似數組 "變量" 的參數中。例如, 在調用 "myFn (a、b、c)"時, 在myFn 的主體內的參數將包含 3個類似數組的元素對應于 (a、b、c)。 使用鉤子修改原型時,只需通過調用該函數的 apply (),將 this 與參數 (調用狀態) 傳遞給當前行為。這種模式可以用于任何原型,如 Node.prototype、 Function.prototype 等.

var current = Object.prototype.valueOf;
// 由于我的屬性 "-prop-value"是交叉性的, 并不總是
// 在同一個原型鏈上,我想要修改 Object.prototype: 
Object.prototype.valueOf = function() {
 if (this.hasOwnProperty('-prop-value')) {
  return this['-prop-value'];
 } else {
  // 它看起來不像我的對象之一,因此,讓我們退回到 
  // 默認行為,通過盡可能地復制當前行為來實現.
  // 此apply的行為類似于其他語言中的"super".
  // 即使 valueOf() 不帶參數, 其他的鉤子可能會帶有.
  return current.apply(this, arguments);
 }
}

從示例不難看出,我可以在某些條件下通過 apply() 方法調用函數原邏輯,某些條件執行我需要的新邏輯。

寫個 demo 測試一下

// 重寫Function的原型方法cache
Function.prototype.cache = function () {
  var _self = this;
  return function() {
 console.log('arguments', arguments);
 var key = arguments[0];
    if (cache.has(key)) {
      return cache.get(key)
    } else {
      return _self.apply(this, arguments)
    }
  }
}

定義 cache,當且僅當 key 為 1 時有值

var cache = {
  has: (key) => {
 if (key === 1) return true
 else return false
  },
  get: (key) => {
    return "cached value " + key
  }
}

定義測試方法

function request(key) {
 return 'value of ' + key
}

應用注入

request = request.cache()

執行一下

request(2)
"value of 2"
request(1)
"cached value 1"

看到結果按照預期輸出,完美!

最后實現

項目引用了 memory-cache 作為基礎緩存庫,實現了相關的緩存功能。

simple-cache.js
const cache = require('memory-cache');
Function.prototype.cache = function (cachekey, time) {
  var _self = this;
  return function() {
 var key = cachekey(arguments);
    var value = cache.get(key);
    if (!value) {
      value = _self.apply(this, arguments)
  cache.put(key, value, time);
    }
    return value;
  }
}
var simpleCache = {
 cache: function(f, cacheKey, cacheTime) {
 return f.cache(cacheKey, cacheTime);
 }
}
module.exports = simpleCache
sample.js
const cache = require('simple-cache-z').cache;
function cachekey(args) {
  return args[0]
}
function request(key) {
  return (new Date()).getTime();
}
request = cache(request, cachekey, 5000);
console.log('request 1 ', request(1));
setTimeout(() => {
  console.log('request 2 ', request(2));
}, 1000)
setTimeout(()=> {
  console.log('request 1 ', request(1))
  console.log('request 1 ', request(1))
  console.log('request 1 ', request(1))
  console.log('request 2 ', request(2));
  console.log('request 2 ', request(2));
  console.log('request 2 ', request(2));
}, 2000);
setTimeout(()=> {
  console.log('request 1 ', request(1));
  console.log('request 1 ', request(1));
  console.log('request 1 ', request(1));
  console.log('request 2 ', request(2));
  console.log('request 2 ', request(2));
  console.log('request 2 ', request(2));
}, 10000);

輸出結果

request 1  1563000551142
// 1000 ms
request 2  1563000552150
// 2000 ms
request 1  1563000551142
request 1  1563000551142
request 1  1563000551142
request 2  1563000552150
request 2  1563000552150
request 2  1563000552150
// 10000 ms
request 1  1563000561151
request 1  1563000561151
request 1  1563000561151
request 2  1563000561151
request 2  1563000561151
request 2  1563000561151

事實證明方案可行,應用到我的項目中對執行效率和代碼可讀性的提升非常明顯。

我已經把框架打成了包,上傳到 npm 倉庫 simple-cache-z ,可通過如下方式引用。

npm install --save simple-cache-z

關于使用Node.js怎么實現一個無侵入式緩存框架就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

韶关市| 繁峙县| 新源县| 原平市| 大竹县| 凤山市| 那坡县| 湖北省| 图木舒克市| 洪洞县| 景宁| 固镇县| 正定县| 隆安县| 运城市| 利津县| 长顺县| 赞皇县| 新民市| 西峡县| 新津县| 民乐县| 华池县| 北辰区| 龙泉市| 绥中县| 丰镇市| 马边| 华坪县| 石门县| 安溪县| 镶黄旗| 巨鹿县| 隆子县| 济阳县| 永安市| 长阳| 松滋市| 荆州市| 沙雅县| 上饶市|