整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          快速了解JavaScript的模塊

          快速了解JavaScript的模塊

          隨著現(xiàn)代 JavaScript 開發(fā) Web 應(yīng)用變得復(fù)雜,命名沖突和依賴關(guān)系也變得難以處理,因此需要模塊化。而引入模塊化,可以避免命名沖突、方便依賴關(guān)系管理、提高了代碼的復(fù)用性和和維護性,因此,在 JavaScript 沒有模塊功能的前提下,只能通過第三方規(guī)范實現(xiàn)模塊化:

          • CommonJS:同步模塊定義,用于服務(wù)器端。
          • AMD:異步模塊定義, 用于瀏覽器端。
          • CMD:異步模塊定義,用于瀏覽器端。
          • UMD:統(tǒng)一 COmmonJSAMD 模塊化方案的定義。

          它們都是基于 JavaScript 的語法和詞法特性 “偽造” 出類似模塊的行為。而 TC-39 在 ECMAScript 2015 中加入了模塊規(guī)范,簡化了上面介紹的模塊加載器,原生意味著可以取代上述的規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案,比使用庫更有效率。而 ES6 的模塊化的設(shè)計目標(biāo):

          • CommonJS 一樣簡單的語法。
          • 模塊必須是靜態(tài)的結(jié)構(gòu)
          • 支持模塊的 異步加載同步加載,能同時用在 serverclient
          • 支持模塊加載的 ‘靈活配置’
          • 更好地支持模塊之間的循環(huán)引用
          • 擁有語言層面的支持,超越 CommonJSAMD

          ECMAScript 在 2015 年開始支持模塊標(biāo)準(zhǔn),此后逐漸發(fā)展,現(xiàn)已經(jīng)得到了所有主流瀏覽器的支持。ECMAScript 2015 版本也被稱為 ECMAScript 6。

          模塊

          ES6 模塊借用了 CommonJSAMD 的很多優(yōu)秀特性,如下所示:

          • 模塊代碼只在加載后執(zhí)行。
          • 模塊只能加載一次。
          • 模塊是單例。
          • 模塊可以定義公共接口,其他模塊可以基于這個公共接口觀察和交互。
          • 模塊可以請求加載其他模塊。
          • 支持循環(huán)依賴。

          ES6 模塊系統(tǒng)也增加了一些新行為。

          • ES6 模塊默認(rèn)在嚴(yán)格模式下執(zhí)行。
          • ES6 模塊不共享全局命名空間。
          • 模塊頂級 this 的值是 undefined;常規(guī)腳本中是 window
          • 模塊中的 var 聲明不會添加到 window 對象。
          • ES6 模塊是異步加載和執(zhí)行的。

          瀏覽器運行時在知道應(yīng)該把某個文件當(dāng)成模塊時,會有條件地按照上述 ES6 模塊行為來施加限制。與 <script type="module"> 關(guān)聯(lián)或者通過 import 語句加載的 JavaScript 文件會被認(rèn)定為模塊。

          導(dǎo)出

          ES6 模塊內(nèi)部的所有變量,外部無法獲取,因此提供了 export 關(guān)鍵字從模塊中導(dǎo)出實時綁定的函數(shù)、對象或原始值,這樣其他程序可以通過 import 關(guān)鍵字使用它們。export 支持兩種導(dǎo)出方式:命名導(dǎo)出和默認(rèn)導(dǎo)出。不同的導(dǎo)出方式對應(yīng)不同的導(dǎo)入方式。

          在 ES6 模塊中,無論是否聲明 "use strict;" 語句,默認(rèn)情況下模塊都是在嚴(yán)格模式下運行。export 語句不能用在嵌入式腳本中。

          命名導(dǎo)出

          通過在聲明的前面加上 export 關(guān)鍵字,一個模塊可以導(dǎo)出多個內(nèi)容。這些導(dǎo)出的內(nèi)容通過名字區(qū)分,被稱為命名導(dǎo)出。

          // 導(dǎo)出單個特性(可以導(dǎo)出 var,let,const)
          export let name="小明";
          export function sayHi(name) {
              console.log(`Hello, ${name}!`);
          }
          export class Sample {
              ...
          }

          或者導(dǎo)出事先定義的特性

          let name="小明";
          const age=18;
          function sayHi(name) {
              console.log(`Hello, ${name}!`);
          }
          export {name, age, sayHi}

          導(dǎo)出時也可以指定別名,別名必須在 export 子句的大括號語法中指定。因此,聲明值、導(dǎo)出值和未導(dǎo)出值提供別名不能在一行完成。

          export {name as username, age, sayHi}

          但導(dǎo)出語句必須在模塊頂級,不能嵌套在某個塊中:

          // 允許
          export ...
          // 不允許
          if (condition) {
              export ...
          }

          默認(rèn)導(dǎo)出

          默認(rèn)導(dǎo)出就好像模塊與被導(dǎo)出的值是一回事。默認(rèn)導(dǎo)出使用 default 關(guān)鍵字將一個值聲明為默認(rèn)導(dǎo)出,每個模塊只能有一個默認(rèn)導(dǎo)出。重復(fù)的默認(rèn)導(dǎo)出會導(dǎo)致 SyntaxError。如下所示:

          // 導(dǎo)出事先定義的特性作為默認(rèn)值
          export default {
              name: "Xiao Ming",
              age: 18,
              sex: "boy"
          };
          export {sayHi as default}    // ES 6 模塊會識別作為別名提供的 default 關(guān)鍵字。此時,雖然對應(yīng)的值是使用命名語法導(dǎo)出的,實際上則會稱為默認(rèn)導(dǎo)出 等同于 export default function sayHi() {}
          // 導(dǎo)出單個特性作為默認(rèn)值
          export default function () {...}
          export default class {...}

          ES6 規(guī)范對不同形式的 export 語句中可以使用什么不可以使用什么規(guī)定了限制。某些形式允許聲明和賦值,某些形式只允許表達(dá)式,而某些形式則只允許簡單標(biāo)識符。注意,有的形式使用了分號,有的則沒有。

          下面列出幾種會導(dǎo)致錯誤的 export 形式:

          // 會導(dǎo)致錯誤的不同形式:
          // 行內(nèi)默認(rèn)導(dǎo)出中不能出現(xiàn)變量聲明
          export default const name='小劉';
          // 只有標(biāo)識符可以出現(xiàn)在export 子句中
          export { 123 as name }
          // 別名只能在export 子句中出現(xiàn)
          export const name='小紅' as uname;

          注意:聲明、賦值和導(dǎo)出標(biāo)識符最好分開。這樣不容易搞錯了,同時也可以讓 export 語句集中在一塊。而且,沒有被 export 關(guān)鍵字導(dǎo)出的變量、函數(shù)或類會在模塊內(nèi)保持私有。

          模塊重定向

          模塊導(dǎo)入的值還可以再次導(dǎo)出,這樣的話,可以在父模塊集中多個模塊的多個導(dǎo)出。可以使用 export from 語法實現(xiàn):

          export {default as m1, name} from './module1.js'
          // 等效于
          import {default as m1, name} from "./module1.js"
          export {m1, name}

          外部模塊的默認(rèn)導(dǎo)出也可以重用為當(dāng)前模塊的默認(rèn)導(dǎo)出:

          export { default } from './module1.js';

          也可以在重新導(dǎo)出時,將導(dǎo)入模塊修改為默認(rèn)導(dǎo)出,如下所示:

          export { name as default } from './module1.js';

          而想要將所有命名導(dǎo)出可以使用如下語法:

          export * from './module1.js';

          該語法會忽略默認(rèn)導(dǎo)出。但這種語法也要注意導(dǎo)出名稱是否沖突。如下所示:

          // module1.js
          export const name="module1:name";
          // module2.js
          export * from './mudule1.js'
          export const name="module2:name";
          // index.js
          import { name } from './module2.js';
          console.log(name); // module2:name

          最終輸出的是 module2.js 中的值,這個 “重寫” 是靜默發(fā)生的。

          導(dǎo)入

          使用 export 關(guān)鍵字定義了模塊的對外接口以后,其它模塊就能通過 import 關(guān)鍵字加載這個模塊了。但與 export 類似,import 也必須出現(xiàn)在模塊的頂級:

          // 允許
          import ...
          // 不允許
          if (condition) {
              import ...
          }

          模塊標(biāo)識符可以是相對于當(dāng)前模塊的相對路徑,也可以是指向模塊文件的絕對路徑。它必須是純字符串,不能是動態(tài)計算的結(jié)果。例如,不能是拼接的字符串。

          當(dāng)使用 export 命名導(dǎo)出時,可以使用 * 批量獲取并賦值給保存導(dǎo)出集合的別名,而無須列出每個標(biāo)識符:

          const name="Xiao Ming", age=18, sex="boy";
          export {name, age, sex}
          
          // 上面的命名導(dǎo)出可以使用如下形式導(dǎo)入(上面的代碼是在 module1.js 模塊中)
          import * as Sample from "./module1.js"
          console.log(`My name is ${Sample.name}, A ${Sample.sex},${Sample.age} years old.`);

          也可以指名導(dǎo)入,只需要把名字放在 {} 中即可:

          import {name, sex as s, age} from "./module1.js";
          console.log(`My name is ${name}, A ${s},${age} years old.`);

          import 引入是采用的 Singleton 模式,多次使用 import 引入同一個模塊時,只會引入一次該模塊的實例:

          import {name, age} from "./module1.js";
          import {sex as s} from "./module1.js";
          // 等同于,并且只會引入一個 module1.js 實例
          import {name, sex as s, age} from "./module1.js";

          而使用默認(rèn)導(dǎo)出的話,可以使用 default 關(guān)鍵字并提供別名來導(dǎo)入,也可以直接使用標(biāo)識符就是默認(rèn)導(dǎo)出的別名導(dǎo)入:

          import {default as Sample} from "./module1.js"
          // 與下面的方式等效
          import Sample from "./module1.js"

          而模塊中同時有命名導(dǎo)出和默認(rèn)導(dǎo)出,可以在 import 語句中同時導(dǎo)入。下面三種方式都等效。

          import Sample, {sayHi} from "./module1.js"
          import {default as Sample, sayHi} from "./module1.js"
          import Sample, * as M1 from "./module1.js"

          當(dāng)然,也可以將整個模塊作為副作用而導(dǎo)入,而不導(dǎo)入模塊中的特定內(nèi)容。這將運行模塊中的全局代碼,但實際上不導(dǎo)入任何值。

          import './module1.js'

          import 導(dǎo)入的值與 export 導(dǎo)出的值是綁定關(guān)系,綁定是不可變的。因此,import 對所導(dǎo)入的模塊是只讀的。但是可以通過調(diào)用被導(dǎo)入模塊的函數(shù)來達(dá)到目的。

          import Sample, * as M1 from "./module1.js"
          Sample="Modify Sample";    // 錯誤
          M1.module1="Module 1";    // 錯誤
          Sample.name="小亮";       // 允許

          這樣做的好處是能夠支持循環(huán)依賴,并且一個大的模塊可以拆成若干個小模塊時也可以運行,只要不嘗試修改導(dǎo)入的值。

          注意:如果要在瀏覽器中原生加載模塊,則文件必須帶有 .js 擴展名,不然可能無法解析。而使用構(gòu)建工具或第三方模塊加載器打包或解析 ES6 模塊,可能不需要包含擴展名。

          import()

          標(biāo)準(zhǔn)的 import 關(guān)鍵字導(dǎo)入模塊是靜態(tài)的,會使所有被導(dǎo)入的模塊,在加載時就被編譯。而最新的 ES11 標(biāo)準(zhǔn)中引入了動態(tài)導(dǎo)入函數(shù) import(),不必預(yù)先加載所有模塊。該函數(shù)會將模塊的路徑作為參數(shù),并返回一個 Promise,在它的 then 回調(diào)里使用加載后的模塊:

          import ('./module1.mjs')
              .then((module)=> {
                  // Do something with the module.
              });

          這種使用方式也支持 await 關(guān)鍵字。

          let module=await import('./module1.js');

          import() 的使用場景如下:

          • 按需加載。
          • 動態(tài)構(gòu)建模塊路徑。
          • 條件加載。

          加載

          ES6 模塊既可以通過瀏覽器原生加載,也可以與第三方加載器和構(gòu)建工具一起加載。

          完全支持 ES6 模塊的瀏覽器可以從頂級模塊異步加載整個依賴圖。瀏覽器會解析入口模塊,確定依賴,并發(fā)送對依賴模塊的請求。這些文件通過網(wǎng)絡(luò)返回后,瀏覽器會解析它們的內(nèi)容,確認(rèn)依賴,如果二級依賴還沒有加載,則會發(fā)送更多請求。這個異步遞歸加載過程會持續(xù)到整個依賴圖都解析完成。解析完依賴,應(yīng)用就可以正式加載模塊了。

          模塊文件按需加載,且后續(xù)模塊的請求會因為每個依賴模塊的網(wǎng)絡(luò)延遲而同步延遲。即,module1 依賴 module2module2 依賴 module3。瀏覽器在對 module2 的請求完成之前并不知道要請求 module3。這種架子啊方式效率高,也不需要外部工具,但加載大型應(yīng)用的深度依賴圖可能要花費很長時間。

          HTML

          想要在 HTML 頁面中使用 ES6 模塊,需要將 type="module" 屬性放在 <script> 標(biāo)簽中,來聲明該 <script> 所包含的代碼在瀏覽器中作為模塊執(zhí)行。它可以嵌入在網(wǎng)頁中,也可以作為外部文件引入:

          <script type="module">
              // 模塊代碼
          </script>
          <script type="module" src="./module1.js"></script>

          <script type="module">模塊加載的順序與 <script defer> 加載的腳本一樣按順序執(zhí)行。但執(zhí)行會延遲到文檔解析完成,但執(zhí)行順序就是<script type="module">在頁面中出現(xiàn)的順序。

          也可以給模塊標(biāo)簽添加 async 屬性。這樣影響是雙重的,不僅模塊執(zhí)行順序不再與 <script> 標(biāo)簽在頁面中的順序綁定,模塊也不會等待文檔完成解析才執(zhí)行。不過,入口模塊必須等待其依賴加載完成。

          Worker

          Worker 為了支持 ES6 模塊,在 Worker 構(gòu)造函數(shù)中可以接收第二個參數(shù),其 type 屬性的默認(rèn)值是 classic,可以將 type 設(shè)置為 module 來加載模塊文件。如下所示:

          // 第二個參數(shù)默認(rèn)為{ type: 'classic' }
          const scriptWorker=new Worker('scriptWorker.js');
          const moduleWorker=new Worker('moduleWorker.js', { type: 'module' });

          在基于模塊的工作者內(nèi)部,self.importScripts() 方法通常用于在基于腳本的工作者中加載外部腳本,調(diào)用它會拋出錯誤。這是因為模塊的 import 行為包含了 importScripts()

          向后兼容

          如果瀏覽器原生支持 ES6 模塊,可以直接使用,而不支持的瀏覽器可以使用第三方模塊系統(tǒng)(System.js)或在構(gòu)建時將 ES6 模塊進行轉(zhuǎn)譯。

          腳本模塊可以使用 type="module" 屬性設(shè)定,而對于不支持模塊的瀏覽器,可以使用 nomodule 屬性。此屬性會通知支持 ES6 模塊的瀏覽器不執(zhí)行腳本。不支持模塊的瀏覽器無法識別該屬性,從而忽略該屬性。如下所示:

          // 支持模塊的瀏覽器會執(zhí)行這段腳本
          // 不支持模塊的瀏覽器不會執(zhí)行這段腳本
          <script type="module" src="module.js"></script>
          // 支持模塊的瀏覽器不會執(zhí)行這段腳本
          // 不支持模塊的瀏覽器會執(zhí)行這段腳本
          <script nomodule src="script.js"></script>

          總結(jié)

          ES6 在語言層面上支持了模塊,結(jié)束了 CommonJSAMD 這兩個模塊加載器的長期分裂狀況,重新定義了模塊功能,集兩個規(guī)范于一身,并通過簡單的語法聲明來暴露。

          模塊的使用不同方式加載 .js 文件,它與腳本有很大的不同:

          1. 模塊始終使用 use strict 執(zhí)行嚴(yán)格模式。
          2. 在模塊的頂級作用域創(chuàng)建的變量,不會被自動添加到共享的全局作用域,它們只會在模塊頂級作用域的內(nèi)部存在。
          3. 模塊頂級作用域的 this 值為 undefined
          4. 模塊不允許在代碼中使用 HTML 風(fēng)格的注釋。
          5. 對于需要讓模塊外部代碼訪問的內(nèi)容,模塊必須導(dǎo)出它們。
          6. 允許模塊從其他模塊導(dǎo)入綁定。
          7. 模塊代碼執(zhí)行一次。導(dǎo)出僅創(chuàng)建一次,然后會在導(dǎo)入之間共享。

          瀏覽器對原生模塊的支持越來越好,但也提供了穩(wěn)健的工具以實現(xiàn)從不支持到支持 ES6 模塊的過渡。

          、為什么用命令行模式

          使用GUI方式啟動jmeter,運行線程較多的測試時,會造成內(nèi)存和CPU的大量消耗,導(dǎo)致客戶機卡死;

          所以一般采用的方式是在GUI模式下調(diào)整測試腳本,再用命令行模式執(zhí)行;

          命令行方式支持在多個環(huán)境下使用,windosw的dos環(huán)境下,也可以在linux環(huán)境上執(zhí)行。

          注意:使用命令執(zhí)行jmeter腳本必須使用jmeter 3.0及以上版本

          2、怎么用

          2.1、執(zhí)行命令

          jmeter -n -t <testplan filename> -l <listener filename>
          
          示例: jmeter -n -t testplan.jmx -l test.jtl
          
          示例含義:表示以命令行模式運行testplan.jmx文件,輸出的日志文件為test.jtl

          2.2、參數(shù)介紹

          Jmeter官方手冊給的介紹如下:

          -h, –help -> prints usage information and exit
          -n, –nongui -> run JMeter in nongui mode
          -t, –testfile <argument> -> the jmeter test(.jmx) file to run
          -l, –logfile <argument> -> the file to log samples to
          -r, –runremote -> Start remote servers (as defined in remote_hosts)
          -H, –proxyHost <argument> -> Set a proxy server for JMeter to use
          -P, –proxyPort <argument> -> Set proxy server port for JMeter to use

          中文釋義:

          -h 幫助 -> 打印出有用的信息并退出
          
          -n 非 GUI 模式 -> 在非 GUI 模式下運行 JMeter
          
          -t 測試文件 -> 要運行的 JMeter 測試腳本文件
          
          -l 日志文件 -> 記錄結(jié)果的文件
          

          -R 遠(yuǎn)程執(zhí)行 -> 遠(yuǎn)程執(zhí)行機的IP(ip地址)如果有多個ip時,使用-R 192.168.2.170,192.168.2.171(分布式使用)

          -r 遠(yuǎn)程執(zhí)行 -> 在Jmter.properties文件中指定的所有遠(yuǎn)程服務(wù)器(分布式使用)
          
          -H 代理主機 -> 設(shè)置 JMeter 使用的代理主機
          
          -P 代理端口 -> 設(shè)置 JMeter 使用的代理主機的端口號

          2.3、執(zhí)行過程

          命令:jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -l report-result.jtl

          不在jmeter安卓目錄執(zhí)行腳本的前提是配置了jmeter的環(huán)境變量。

          2.4、報告查看

          上述的命令有測試結(jié)果保存到D:\report中,在GUI模式下查看測試報告:

          1、在測試計劃下,添加對應(yīng)的測試報告元件,舉例增加了:查看結(jié)果樹、聚合報告

          2、在“所有數(shù)據(jù)寫入一個文件”,選擇加載對應(yīng)的結(jié)果文件

          3、下面就會有對應(yīng)的表格展示,具體見下圖

          2.5、命令行傳遞變量值

          設(shè)置線程組的線程數(shù)和循環(huán)次數(shù)。

          注意格式:

          ${__P(threadNum)}

          ${__P(threadCount)}

          其中P前面是兩個下劃線,()內(nèi)就是變量名

          執(zhí)行時,在命令行中用-J參數(shù)給變量賦值即可:

          jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -J threadNum=10 -J threadCount=2 -l report-result.jtl

          此次測試相當(dāng)于:10個線程,循環(huán)2次,共計20個請求。

          3、生成HTML報告

          生成HTML報告有2種方式,一種是直接在命令行加上-o參數(shù),另一種是已有jtl結(jié)果文件,運行命令生成報告

          3.1、命令行直接生成報告

          jmeter -n -t 【Jmx腳本位置】-l 【中間文件result.jtl位置】-e -o 【報告指定文件夾】
          -e:測試結(jié)束后,生成測試報告
          -o:指定測試報告的存放位置

          注意:-o后面跟的文件夾一定是不存在的或者是空文件夾

          3.2、已有jtl結(jié)果文件,運行命令生成報告

          jmeter -g【已經(jīng)存在的.jtl文件的路徑】-o 【用于存放html報告的目錄】

          注意:經(jīng)實操,windows系統(tǒng)上,以上2種方法都可以生成HTML測試報告,但是在Linux系統(tǒng)上第1種方法,沒有生成報告,只有第二種方法才可以(具體原因后面在慢慢找吧)

          3.3、HTML報告注解

          用瀏覽器打開index.html

          報告詳解

          Dashboard:(重點查看)
          Test and Report informations:指的是測試和報告信息

          • File:測試結(jié)果的保存文件名稱
          • Start Time:測試開始時間
          • End Time:測試結(jié)束時間
          • Filter for display展示過濾器

          APDEX(Application Performance Index):應(yīng)用程序性能滿意度的標(biāo)準(zhǔn)

          其中,

          • “Apdex”范圍在0-1之間,1表示達(dá)到所有用戶均滿意,越接近1滿意度越高
          • “toleration threshold”:耐受閾值(0.5秒)
          • “frustration threshold”:挫敗閾值(1.5秒)

          Requests Summary:請求的通過率(OK)與失敗率(KO),百分比顯示

          Statistics:數(shù)據(jù)分析,基本將Summary Report和Aggrerate Report的結(jié)果合并(平均響應(yīng)時間、TPS在此查看)

          Errors:錯誤情況,依據(jù)不同的錯誤類型,將所有錯誤結(jié)果展示

          關(guān)于Apdex的補充:

          性能指數(shù),Apdex(Application Performance Index)是一個國際通用標(biāo)準(zhǔn),Apdex 是用戶對應(yīng)用性能滿意度的量化值。它提供了一個統(tǒng)一的測量和報告用戶體驗的方法,把最終用戶的體驗和應(yīng)用性能作為一個完整的指標(biāo)進行統(tǒng)一度量。下圖表示為通用用戶滿意度區(qū)域,0代表沒有滿意用戶,1則代表所有用戶都滿意。實際業(yè)務(wù)系統(tǒng)開發(fā)過程中,1是團隊的追求目標(biāo)。

          若所有請求的Apdex值都接近1,說明用戶滿意度優(yōu)秀,也從側(cè)面說明了服務(wù)器響應(yīng)速度快。
          通常而言,
          最低要求超過0.5,當(dāng)然項目組可設(shè)定具體需求。

          Charts:(輔助分析)

          主要有如下特點:
          (1)將測試過程中經(jīng)常使用的數(shù)據(jù),用圖表的形式展示,讓測試結(jié)果更加直觀
          (2)每個圖表數(shù)據(jù),有兩種展示形式
          (3)支持請求樣例過濾顯示
          (4)支持導(dǎo)出PNG圖片格式

          Over Time Charts

          • Response Times Over Time:每秒鐘響應(yīng)時間,X軸表示的是系統(tǒng)運行的時刻,Y軸表示的是響應(yīng)時間,F(xiàn)(X,Y)表示系統(tǒng)隨著時間的推移,系統(tǒng)的響應(yīng)時間的變化,可以看出響應(yīng)時間穩(wěn)定性
          • Bytes Throughput Over Time:字節(jié)接收與發(fā)送的數(shù)量,每秒傳輸字節(jié)吞吐量,表明Jmeter在測試時,隨著時間推移發(fā)送和接收的字節(jié)數(shù)
          • Latencies Over Time:延遲時間

          Throughput Charts

          • Hits Per Second: 每秒點擊率
          • Codes Per Second:每秒狀態(tài)碼數(shù)量
          • Transactions Per Second:每秒事務(wù)量
          • Response Time Vs Request:響應(yīng)時間點請求的成功與失敗數(shù)
          • Latency Vs Request:延遲時間點請求的成功與失敗數(shù)

          Response Times Charts

          • Response Time Percentiles:響應(yīng)時間百分比
          • Active Threads Over Time:激活線程數(shù)
          • Time Vs Threads:響應(yīng)時間用戶數(shù), X軸表示的是活動線程數(shù),也就是并發(fā)訪問的用戶數(shù),Y軸表示的是響應(yīng)時間,F(xiàn)(X,Y)表示在某種并發(fā)量的情況下,系統(tǒng)的響應(yīng)時間是多少
          • Response Time Distribution:響應(yīng)時間分布

          3.4、HTML報告的自定義配置

          JMeter3.0開始在bin目錄新增了reportgenerator.properties文件保存了所有關(guān)于圖形化HTML報告生成模塊的默認(rèn)配置,要變更配置,建議不要直接編輯該文件,而是推薦在user.properties中去配置和覆蓋。

          3.4.1總體配置

          總體配置都是以jmeter.reportgenerator.為前綴,如:jmeter.reportgenerator.overall_granularity=60000

          • overall_granularity:定義采樣點粒度,默認(rèn)為60000ms,通常在穩(wěn)定性以外的測試中,我們可能需要定義更細(xì)的粒度,比如1000ms,我們可以在user.properties文件末尾添加如下配置
          # Change this parameter if you want to change the granularity of over time graphs.
          jmeter.reportgenerator.overall_granularity=6000
          • report_title:定義報告的標(biāo)題,我們可能需要將標(biāo)題定義為實際測試項名稱
          • apdex_satisfied_threshold:定義Apdex評估中滿意的閾值(單位ms)
          • apdex_tolerated_threshold: 定義Apdex評估中可容忍的閾值

          Apdext=(Satisfied Count + Tolerating Count / 2) / Total Samples


          另外,在jmeter.properties中,有關(guān)于集合報告中的三個百分位的默認(rèn)值:

          aggregate_rpt_pct1 : Defaults to 50
          aggregate_rpt_pct2 : Defaults to 70
          aggregate_rpt_pct3 : Defaults to 99

          3.5、HTML報告的定制

          JMeter的HTML報告生成時是使用了固定的模板,模板文件路徑為./bin/report-template。
          進入該目錄可以看到報告的每個頁面都有一個.fmkr模板文件,包括index.html.fmkr和./content/pages路徑下的幾個文件。通過查看這些模板文件,就可以知道怎樣去進行報告的輕度定制,比如將一些文本修改得更易懂,或者修改為中文等

          頁面的title
          默認(rèn)為"Apache JMeter Dashboard"
          可以由reportgenerator.properties中的jmeter.reportgenerator.report_title來統(tǒng)一定義,這種方式就是所有頁面的title都使用同一個。
          也可以直接修改對應(yīng)的.fmkr文件中的title標(biāo)簽中雙引號內(nèi)的值,如<title>${reportTitle!"想要設(shè)置的title"}</title>,這中方式可以為每個頁面單獨定義title
          圖表的名稱
          當(dāng)前版本下,各圖表的名稱是直接在模板文件中定義,要修改也是直接修改模板文件中對應(yīng)元素的值即可
          如要修改Transactions Per Second圖表的名稱,可以直接在./content/pages/Throughput.html.fmkr文件中修改,效果如下圖

          odash, Moment, Axios, Async... 這些是有用的JavaScript庫,您希望在許多Vue.js應(yīng)用程序中使用這些庫。

          但是,隨著項目的發(fā)展,您將將代碼分離為單個文件組件和模塊文件。您還可能希望在不同的環(huán)境中運行您的應(yīng)用程序,以允許服務(wù)器呈現(xiàn)。

          除非您找到一種簡單而健壯的方法將這些JavaScript庫包含在組件和模塊文件中,否則它們將是一個麻煩!



          多么不在Vue.js項目中包含一個庫

          全局變量

          將庫添加到項目中的天真方法是通過將庫附加到window目的:

          entry.js

          JavaScript

          window._=require('lodash');

          MyComponent.vue

          JavaScript

          export default { created() { console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..'); }}

          針對窗口變量的情況很長,但是,特別是在本討論中,它們不適用于服務(wù)器呈現(xiàn)。當(dāng)應(yīng)用程序在服務(wù)器上運行時,window對象將是未定義的,因此試圖訪問屬性將以錯誤結(jié)束。

          導(dǎo)入每個文件

          另一種二流方法是將庫導(dǎo)入到每個文件中:

          MyComponent.vue

          JavaScript

          import _ from 'lodash';
          export default {
          created() {
          console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
          }
          }

          這是可行的,但它并不是很干燥,而且基本上是一種痛苦:您必須記住將它導(dǎo)入到每個文件中,如果您停止在該文件中使用它,則再次刪除它。如果您沒有正確地設(shè)置您的構(gòu)建工具,那么您的構(gòu)建中可能會有多個相同庫的副本。

          更好的方法

          在Vue項目中使用JavaScript庫的最干凈和最健壯的方法是將其代理到Vue Prototype對象的屬性。讓我們這樣做,將時間、日期和時間庫添加到我們的項目中:

          entry.js

          JavaScript

          import moment from 'moment';

          Object.definePrototype(Vue.prototype, '$moment', { value: moment });

          由于所有組件都從Vue Prototype對象繼承它們的方法,這將使所有組件都可以在沒有全局變量或手動導(dǎo)入的任何組件中自動使用。可以簡單地在任何實例/組件中訪問this.$moment:

          MyNewComponent.vue

          JavaScript

          export default {
          created() {
          console.log('The time is ' . this.$moment().format("HH:mm"));
          }
          }

          現(xiàn)在讓我們花時間了解一下這是如何工作的。

          Object.defineProperty

          我們通常會設(shè)置如下對象屬性:

          JavaScript

          Vue.prototype.$moment=moment;

          你可以在這里做,但是Object.defineProperty相反,我們可以使用descriptor。描述符允許我們設(shè)置一些低級別的詳細(xì)信息,例如我們的屬性是否可寫,以及它是否在枚舉期間顯示在for循環(huán)等等。


          在日常的JavaScript中,我們通常不會考慮這個問題,因為99%的時間我們都不需要這樣的細(xì)節(jié)來分配屬性。但是在這里,它給了我們一個明顯的優(yōu)勢:用描述符創(chuàng)建的屬性是只讀默認(rèn)情況下。

          這意味著,一些缺少咖啡的開發(fā)人員(可能是您)無法在組件中做一些愚蠢的事情,從而破壞一切:

          JavaScript

          this.$http='Assign some random thing to the instance method';

          this.$http.get('/'); // TypeError: this.$http.get is not a function


          相反,我們的只讀實例方法保護我們的庫,如果您試圖覆蓋它,您將得到“TypeError:NotAssistto只讀屬性”。

          $

          您會注意到,我們將我們的庫代理到一個以美元符號“$”為前綴的屬性名。您可能還看到了其他屬性和方法,如$refs, $on, $mount,等等,它們也有這個前綴。

          雖然不是必需的,但前綴被添加到屬性中,以提醒缺乏咖啡的開發(fā)人員(再次),這是一個歡迎您使用的公共API屬性或方法,與實例的其他屬性不同,這些屬性可能只是用于Vue的內(nèi)部使用。

          作為一種基于原型的語言,JavaScript中沒有(真正的)類,因此它沒有“私有”和“公共”變量或“靜態(tài)”方法。這個公約是一個溫和的替代,我認(rèn)為是值得遵循的。


          您還會注意到要使用您使用的庫this.libraryName這可能并不令人驚訝,因為它現(xiàn)在是一個實例方法。

          但是,這樣做的一個結(jié)果是,與全局變量不同,您必須確保在使用庫時處于正確的范圍內(nèi)。在回調(diào)方法中,無法訪問this你的圖書館住的地方。

          FAT箭頭回調(diào)是確保您保持在正確范圍內(nèi)的一個很好的解決方案:

          JavaScript

          this.$http.get('/').then(res=> {
          if (res.status !==200) {
          this.$http.get('/') // etc
          // Only works in a fat arrow callback.
          }
          });


          為什么不把它變成插件呢?

          如果您計劃在多個Vue項目中使用一個庫,或者您想要與世界共享它,您可以將其構(gòu)建到您自己的插件中!

          插件抽象了復(fù)雜性,并允許您在項目中簡單地執(zhí)行以下操作以添加所選庫:

          JavaScript

          import MyLibraryPlugin from 'my-library-plugin';

          Vue.use(MyLibraryPlugin);

          使用這兩行,我們可以在任何組件中使用庫,就像我們可以使用Vue路由器、Vuex和其他利用Vue.use.


          編寫插件

          首先,為插件創(chuàng)建一個文件。在本例中,我將制作一個插件,將Axios添加到所有Vue實例和組件中,因此我將調(diào)用該文件axios.js.

          主要要了解的是,插件必須公開install方法,它將Vue構(gòu)造函數(shù)作為第一個參數(shù):

          axios.js

          JavaScript

          export default {
          install: function(Vue) {
          // Do stuff
          }
          }

          現(xiàn)在,我們可以使用前面的方法將庫添加到Prototype對象中:

          axios.js

          JavaScript

          import axios from 'axios';
          export default {
          install: function(Vue,) {
          Object.defineProperty(Vue.prototype, '$http', { value: axios });
          }
          }


          這個use實例方法是將庫添加到項目中所需的全部內(nèi)容。例如,我們現(xiàn)在可以像這樣輕松地添加Axios庫:

          entry.js

          JavaScript

          import AxiosPlugin from './axios.js';
          Vue.use(AxiosPlugin);
          new Vue({
          created() {
          console.log(this.$http ? 'Axios works!' : 'Uh oh..');
          }
          })

          獎勵:插件可選參數(shù)

          插件安裝方法可以采用可選參數(shù)。有些開發(fā)人員可能不喜歡調(diào)用他們的Axios實例方法。$http由于Vue Resource通常被命名為Vue Resource,所以讓我們使用一個可選的參數(shù)來允許他們將其更改為他們喜歡的任何東西:

          axios.js

          JavaScript

          import axios from 'axios';
          export default {
          install: function(Vue, name='$http') {
          Object.defineProperty(Vue.prototype, name, { value: axios });
          }
          }


          entry.js

          JavaScript

          import AxiosPlugin from './axios.js';
          Vue.use(AxiosPlugin, '$axios');
          new Vue({
          created() {
          console.log(this.$axios ? 'Axios works!' : 'Uh oh..');
          }
          })

          為感謝您對我們的認(rèn)可,特意準(zhǔn)備了一些IT入門和進階的干貨

          包括:Java、UI設(shè)計、H5前端、Python+人工智能、軟件測試和新媒體運營六大學(xué)科視頻資料。以及IT就業(yè)大禮包。

          線上視頻、音頻,隨時學(xué)習(xí)觀看

          關(guān)注我們并私信“資料”即可獲取。


          主站蜘蛛池模板: 精品国产日韩亚洲一区在线| 亚洲一区精彩视频| 精品免费久久久久国产一区| 国产在线一区观看| 日本免费一区二区三区最新 | 丰满人妻一区二区三区视频53| 国产伦精品一区二区三区精品| 日韩精品一区二区三区老鸦窝| 日韩福利视频一区| 无码国产精品一区二区免费| 无码日韩精品一区二区免费暖暖 | 成人免费视频一区| 国产精品无码一区二区三区不卡| 国产在线aaa片一区二区99| 日韩一区二区三区视频| 日本美女一区二区三区| 人妻精品无码一区二区三区| 日韩人妻无码一区二区三区 | 国偷自产Av一区二区三区吞精| 免费一区二区三区| 在线观看中文字幕一区| 岛国无码av不卡一区二区 | 亚洲AV日韩AV一区二区三曲| 国产91一区二区在线播放不卡 | 国产亚洲欧洲Aⅴ综合一区| 亚洲视频一区在线观看| 一区二区视频在线免费观看| 日韩人妻精品无码一区二区三区 | 无码日韩人妻AV一区二区三区| 色窝窝无码一区二区三区 | 日韩AV无码一区二区三区不卡毛片 | 亚洲一区二区三区自拍公司| 国产精品视频免费一区二区| 国产主播一区二区| 福利片免费一区二区三区| 亚洲福利一区二区三区| 中文字幕一区二区三区精华液| 毛片一区二区三区无码| 日韩一区二区三区无码影院| 精品久久久久中文字幕一区| 日本一区二区三区日本免费|