ES6-ES11最通俗易懂保姆級的筆記!人見人愛,花見花開。趕快動起你發財的小手收藏起來吧,滿滿的乾貨,你值得擁有!!

来源:https://www.cnblogs.com/liushihong21/archive/2023/09/10/17678185.html
-Advertisement-
Play Games

功能介紹 登錄 首頁 修改密碼 提交申請 提交列表 數據可視化 審核列表 前端 components結構 搭建Vue項目 ​ Vue3快速上手: ​ https://cn.vuejs.org/guide/quick-start.html#creating-a-vue-application 頁面佈局 ...


1.  ES6

1.1  let變數聲明以及聲明特性

聲明變數

let a;
let b, c, e;
let f = 100,
g = "紅石榴21",
h = [];

特性:

  • 變數不能重覆聲明
let start = "許巍";
let start = "刀郎"; // 報錯
  • 塊級作用域 全局、函數、eval
{
   let str = "紅石榴21"
}
console.log(str); // str is not defined
不僅僅針對花括弧,if else while for中都是塊級作用域
  • 不存在變數提升
console.log(song);
let song = "羅剎海市";  // Cannot access 'song' before initialization
  • 不影響作用域鏈
{
  let school = "國防科技大學";
  function fn() {
    console.log(school); // 國防科技大學
  }
  fn();
}

 案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>let經典案例實踐</title>
    <link
      crossorigin="anonymous"
      href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h2 class="page-header">點擊切換顏色</h2>
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
    <style>
      .item {
        width: 100px;
        height: 50px;
        border: solid 1px rgb(42, 156, 156);
        float: left;
        margin-right: 10px;
      }
    </style>
    <script>
      let items = document.getElementsByClassName("item");
      // for (var i = 0; i < items.length; i++) {
      //   items[i].onclick = function () {
      //     this.style.background = "pink"; // for迴圈中,不使用let聲明
      //   };
      // }
      for (let i = 0; i < items.length; i++) {
        items[i].onclick = function () {
          items[i].style.background = "pink"; // for迴圈中,使用let聲明
        };
      }
    </script>
  </body>
</html>

1.2  const聲明常量以及特點

常量聲明
const SCHOOL = "西南石油大學";
特性:
  • 一定要賦初始值
 const A; // 報錯
  • 一般變數使用大寫(潛規則)
const A = 100;
  • 常量的值不能被修改
SCHOOL = "國防科技大學";
console.log(SCHOOL); // Assignment to constant variable.
  • 塊級作用域
{
  const YWZQ = "go";
}
console.log(YWZQ); // YWZQ is not defined
  • 對於數組和對象元素的修改,不算對常量的修改,不會報錯
const LIKE = ["HG", "MC", "LZZ"];
LIKE.push("ZZC");
console.log(LIKE); // ['HG', 'MC', 'LZZ', 'ZZC']

1.3  變數的解構賦值

ES6 允許按照一定模式從數組和對象中提取值,對變數進行賦值,這被稱為解構賦值。
  • 數組結構賦值
const F4 = ["小沈陽", "趙四", "劉能", "宋小寶"];
let [xiao, zhao, liu, song] = F4;
console.log(xiao); // 小沈陽
console.log(zhao); // 趙四
console.log(liu); // 劉能
console.log(song); // 宋小寶
  • 對象結構賦值
const zhao = {
  name: "趙本山",
  age: "65",
  xiaoping: function () {
    console.log("我會演小品");
  },
};
let { name, age, xiaoping } = zhao;
console.log(name); // 趙本山
console.log(age); // 65
console.log(xiaoping); // 輸出ƒ(){}
xiaoping(); // 我會演小品
如果不用結構的形式
console.log(zhao.name);
console.log(zhao.age);
zhao.xiaoping();
zhao.xiaoping();

1.4  模板字元串

ES6 引入新的聲明字元串的方式 『``』 '' ""
  • 聲明變數
let str = `今天天氣有點熱啊`;
console.log(str);
  • 內容可以直接出現換行符
let str =
  "<ul>" + "<li>張三</li>" + "<li>李四</li>" + "<li>王五</li>" + "</ul>"; // 之前的寫法
let str = 
  `<ul>
    <li>張三1</li>
    <li>李四2</li>
    <li>王五3</li>
  </ul>`;
document.getElementById("appID").innerHTML = str;
  • 字元串的拼接
let str = "許巍"; 
let lovest = `我喜歡${str}的歌,名字叫做<<藍蓮花>>。`;
console.log(lovest);
1.5  對象的簡化寫法 ES6 允許在大括弧裡面,直接寫入變數和函數,作為對象的屬性和方法。 這樣的書寫更加簡潔
let name = "紅石榴21";
let change = function () {
  console.log("我想改變世界!!");
};
const dream = {
  name,
  change,
  // improve: function () {
  //   console.log("我又get到了新的技能!");
  // },
  // 簡寫形式
  improve() {
    console.log("hahaha");
  },
};
dream.change();
dream.improve();

1.6  箭頭函數以及聲明特點

ES6 允許使用「箭頭」(=>)定義函數。 聲明一個函數
let fn = function() {}
let fn = function (a, b) {
    return a + b;
};
// 調用函數
let result = fn(1, 2);
console.log(result); // 3

特性:

  • this 是靜態的,this 始終指向函數聲明時所在作用域下的 this 的值
function getName() {
  console.log(this.name);
}
let getName2 = () => {
  console.log(this.name);
};
// 設置 window 對象的name 屬性
window.name = "紅石榴21";
const school = {
  name: "博商學院",
};
// 直接調用
getName(); // 紅石榴21
getName2(); // 紅石榴21
// call 方法調用
getName.call(school); // 博商學院
getName2.call(school); // 紅石榴21
  • 不能作為構造函數實例化對象
let Person = (name, age) => {
  this.name = name;
  this.age = age;
};
let me = new Person("hong", 18);
console.log(me); // Person is not a constructor
  • 不能使用 arguments 變數
let fn = () => {
  console.log(arguments);
};
fn(1, 2, 3); // arguments is not defined
  • 箭頭函數的簡寫
// 1) 省略小括弧,當形參有且只有一個的時候
let add = n => {
  return n + n;
};
console.log(add(9)); // 18
// 2) 省略花括弧,當代碼體只有一條語句的時候,此時 return 必須省略
// 而且語句的執行結果就是函數的返回值
let pow = (n) => n * n;
console.log(pow(9)); // 81

 箭頭函數的實踐與應用場景

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>箭頭函數的實踐與應用場景</title>
  </head>
  <body>
    <div id="add"></div>
    <style>
      #add {
        width: 200px;
        height: 200px;
        background: #58a;
      }
    </style>
    <script>
      // 需求-1  點擊 div 2s 後顏色變成『粉色』
      // 獲取元素
      let add = document.getElementById("add");
      //綁定事件
      add.addEventListener("click", function () {
        // 1、setTimeout未使用箭頭函數
        //保存 this 的值
        // let _this = this;
        // let that = this;
        // let self = this;
        // setTimeout(function () {
        //   _this.style.background = "pink";
        // }, 2000);
        // 2、setTimeout使用箭頭函數, this 是靜態的
        setTimeout(() => {
          this.style.background = "pink";
        }, 2000);
      });
      // 需求-2  從數組中返回偶數的元素
      const arr = [1, 2, 4, 6, 10, 13];
      // const result = arr.filter(function (item) {
      //   if (item % 2 === 0) {
      //     return true;
      //   } else {
      //     return false;
      //   }
      // });
      // const result = arr.filter((item) => {
      //   if (item % 2 === 0) {
      //     return true;
      //   } else {
      //     return false;
      //   }
      // });
      // 簡寫形式
      const result = arr.filter((item) => item % 2 === 0);
      console.log(result);
      // 箭頭函數適合與 this 無關的回調,定時器,數組的方法回調
      // 箭頭函數不適合與 this 有關的回調,事件回調,對象的方法
    </script>
  </body>
</html>
1.7  函數參數的預設值設置 ES6 允許給函數參數賦值初始值
  • 形參初始值 具有預設值的參數,一般位置要靠後(潛規則)
function add(a, b, c) {
  return a + b + c;
}
let result = add(1, 2, 3);
console.log(result); // 6
// 設置預設值
function add(a, b, c = 4) {
  return a + b + c;
}
let result = add(1, 2);
console.log(result);  // 7
  • 與結構賦值結合
function connect({ host, username, password, port }) {
  console.log(host);
  console.log(username);
  console.log(password);
  console.log(port);
}
connect({
  host: "127.0.0.1",
  username: "admin",
  password: "admin",
  port: 80,
});
1.8  rest參數 ES6 引入 rest 參數,用於獲取函數的實參,用來代替 arguments ES5 獲取實參的方式
function date() {
  console.log(arguments);
}
date("俞老師", "王老師", "顧老師");

rest 參數

function date(...args) {
  console.log(args); // [俞老師", "王老師", "顧老師] 變成數組就可以使用 filter、some、every、map
}
date("俞老師", "王老師", "顧老師");
rest 參數必須要放到參數最後
function fn(a, b, ...args) {
  console.log(a); // 1
  console.log(b); // 2
  console.log(args); // [3, 4, 5, 6]
}
fn(1, 2, 3, 4, 5, 6);

1.9  擴展運算符的介紹

『...』 擴展運算符能將『數組』轉換為逗號分隔的『參數序列』
// 聲明一個數組
const tfbody = ["樸樹", "許巍", "刀郎"];
// 聲明一個函數
function likeSinger() {
  console.log(arguments);
}
likeSinger(...tfbody);
console.log(tfbody);

輸出結果

 擴展運算符的應用

  • 數組的合併
const siDaTianWang = ["劉德華", "張學友", "郭富城", "黎明"];
const xiaoHuDui = ["吳奇隆", "陳志朋", "蘇有朋"];
// const zuHe = siDaTianWang.concat(xiaoHuDui); // 使用concat實現數組拼接
// console.log(zuHe); // ["劉德華", "張學友", "郭富城", "黎明","吳奇隆", "陳志朋", "蘇有朋"]
const zuHe = [...siDaTianWang, ...xiaoHuDui];
console.log(zuHe); // ["劉德華", "張學友", "郭富城", "黎明","吳奇隆", "陳志朋", "蘇有朋"]
  • 數組的克隆
const ziMu = ["A", "B", "C"];
const newArr = [...ziMu];
console.log(ziMu); // ["A", "B", "C"]
console.log(newArr); // ["A", "B", "C"]
  • 將偽數組轉為真正的數組
const divS = document.querySelectorAll("div");
const divArr = [...divS];
console.log(divArr);

輸出結果

1.10.1  Symbol的介紹與創建
  • 創建Symbol
let s = Symbol();
console.log(s, typeof s); // Symbol() 'symbol'
let s2 = Symbol("嘀嘀咕咕");
let s3 = Symbol("嘀嘀咕咕");
console.log(s2, typeof s2); // Symbol(嘀嘀咕咕) 'symbol'
console.log(s2 === s3); // false
  • Symbol.for 創建
let s4 = Symbol.for("我的心思");
let s5 = Symbol.for("我的心思");
console.log(s4); // Symbol(我的心思)
console.log(s4 === s5); // true
  • 不能與其他數據進行運算
let result = s + 100; // Cannot convert a Symbol value to a number
let result = s > 100; // Cannot convert a Symbol value to a number
let result = s + s; // Cannot convert a Symbol value to a number
// USONB you are so niubility
// u   undefined
// s   string   symbol
// o   object
// n   null   number
// b   boolean 

1.10.2 對象添加Symbol類型的屬性

向對象中添加方法 up down
let game = {
  name: "學爸",
  up: function () {},
  down: function () {},
};

// 聲明一個對象
let methods = {
  up: Symbol(),
  down: Symbol(),
};
// console.log(methods);

game[methods.up] = function () {
  console.log("我可以改變世界!");
};

game[methods.down] = function () {
  console.log("海鮮都留給小日子吃吧!");
};
console.log(game);

輸出結果

let phws = {
  name: "排核污水",
  [Symbol("say")]: function () {
    console.log("打斷小日子的狗腿");
  },
  [Symbol("woof")]: function () {
    console.log("小日子公開食海鮮,真香");
  },
};
console.log(phws);

輸出結果

1.10.3  Symbol的內置屬性

  • Symbol.hasInstance
當其他對象使用 instanceof 運算符,判斷是否為該對象的實例時,會調用這個方法
class Person {
  static [Symbol.hasInstance](param) {
    console.log(param);
    console.log("我被用來檢測類型了");
    return true;
  }
}
let o = {};
console.log(o instanceof Person);
  • Symbol.isConcatSpreadable
對象的 SymbolisConcatSpreadable 屬性等於的是一個布爾值,表示該對象用於Array.prototype.concat()時,是否可以展開。
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2));

除了定義自己使用的 Symbol 值以外,ES6 還提供了 11個內置的 Symbol值,指向語言內部使用的方法。

1.11.1  迭代器介紹

迭代器(iterator)【對象中的一個屬性】是一種介面,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 iterator 介面,就可以完成遍歷操作。
  • ES6 創造了一種新的遍歷命令 for...of 迴圈,lterator 介面主要供 for...of 消費
  • 原生具備 iterator 介面的數據(可用 for of 遍歷)

a) Array
b) Arguments
c) Set
d) Map
e) String
f) TypedArray
g) NodeList

  • 工作原理

a) 創建一個指針對象,指向當前數據結構的起始位置

b) 第一次調用對象的 next 方法,指針自動指向數據結構的第一個成員

c) 接下來不斷調用 next 方法,指針一直往後移動,直到指向最後一個成員

d) 每調用 next 方法返回一個包含 value 和done 屬性的對象

註:需要自定義遍曆數據的時候,要想到迭代器。

// 聲明一個數組
const tangShengShiTu = ["唐僧", "孫悟空", "豬八戒", "沙和尚"];
// 使用 for...of 遍曆數組
// for (let v of tangShengShiTu) {
//   console.log(v); // "唐僧", "孫悟空", "豬八戒", "沙和尚"
// }

let iterator = tangShengShiTu[Symbol.iterator]();
// 調用對象的next方法
console.log(iterator.next()); // {value: '唐僧', done: false}
console.log(iterator.next()); // {value: '孫悟空', done: false}
console.log(iterator.next()); // {value: '豬八戒', done: false}
console.log(iterator.next()); // {value: '沙和尚', done: false}
console.log(iterator.next()); // {value: '', done: true}

1.11.2   迭代器應用-自定義遍曆數據

// 聲明一個對象
const banJi = {
  name: "朗月班",
  stuList: ["xiaohong", "xiaolian", "xiaojia", "xiaoyuan"],
  [Symbol.iterator]() {
    // 索引變數
    let index = 0;
    // let _this = this;
    // return {
    //   next: function () {
    //     if (index < _this.stuList.length) {
    //       const result = { value: _this.stuList[index], done: false };
    //       // 下標自增
    //       index++;
    //       // 返回結果
    //       return result;
    //     } else {
    //       return { value: _this.stuList[index], done: true };
    //     }
    //   },
    // };
    // 使用箭頭函數
    let next = () => {
      if (index < this.stuList.length) {
        const result = { value: this.stuList[index], done: false };
        // 下標自增
        index++;
        // 返回結果
        return result;
      } else {
        return { value: this.stuList[index], done: true };
      }
    };
    return { next };
  },
};

// 需求: 只能使用for of 遍歷stuList,通過面向對象
// 不能使用 banJi.stuList.forEach
for (let v of banJi) {
  console.log(v); // "xiaohong", "xiaolian", "xiaojia", "xiaoyuan"
}

1.12.1   生成器函數聲明與調用

生成器函數是 ES6 提供的一種非同步編程解決方案,語法行為與傳統函數完全不同

// 生成器其實就是一個特殊的函數
// 非同步編程 純回調函數 node fs ajax mongodb
// 函數代碼的分隔符
function* gen() {
  console.log("hello generator"); // hello generator
}
let iterator = gen();
iterator.next();

另一個例子

function* gen() {
  console.log(111);
  yield "光輝歲月";
  console.log(222);
  yield "藍蓮花";
  console.log(333);
  yield "像風一樣自由";
  console.log(444);
}
let iterator = gen();
console.log(iterator.next()); // 111 {value: '光輝歲月', done: false}
console.log(iterator.next()); // 222 {value: '藍蓮花', done: false}
console.log(iterator.next()); // 333 {value: '像風一樣自由', done: false}
console.log(iterator.next()); // 444 {value: 'undefined', done: true}
// 遍歷
for (let v of gen()) {
  console.log(v);
}

遍歷輸出結果

1.12.2   生成器函數的參數傳遞

function* gen() {
  yield 111;
  yield 222;
  yield 333;
}
// 執行獲取迭代器對象
let iterator = gen();
console.log(iterator.next()); // {value: 111, done: false}
console.log(iterator.next()); // {value: 222, done: false}
console.log(iterator.next()); // {value: 333, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

另一個例子

function* gen(arg) {
  console.log(arg);
  let one = yield 111;
  console.log(one);
  let two = yield 222;
  console.log(two);
  let three = yield 333;
  console.log(three);
}

// 執行獲取迭代器對象
let iterator = gen("AAA");
console.log(iterator.next());
// next方法可以傳入實參
console.log(iterator.next("BBB")); // 第二次調用作為第一個yield的返回參數
console.log(iterator.next("CCC")); // 第三次調用作為第二個yield的返回參數
console.log(iterator.next("DDD")); // 第四次調用作為第三個yield的返回參數
console.log(iterator.next("FFF"));

輸出結果

1.12.3   生成器函數實例 非同步編程 文件操作 網路操作(ajax, request) 資料庫操作 需求-1 1s 後控制台輸出 111 2s 後控制台輸出 222 3s 後控制台輸出 333   // 這種調用方式叫做回調地獄
setTimeout(() => {
  console.log(111);
  setTimeout(() => {
    console.log(222);
    setTimeout(() => {
      console.log(333);
    }, 3000);
  }, 2000);
}, 1000);

另一個例子

function one() {
  setTimeout(() => {
    console.log(111);
    iterator.next();
  }, 1000);
}
function two() {
  setTimeout(() => {
    console.log(222);
    iterator.next();
  }, 2000);
}
function three() {
  setTimeout(() => {
    console.log(333);
  }, 3000);
}
function* gen() {
  yield one();
  yield two();
  yield three();
}
// 調用生成器函數
let iterator = gen();
iterator.next();

輸出結果

1.12.4   生成器函數實例-2

需求-2 模擬獲取 先調用用戶數據,然後調用訂單數據,最後調用商品數據
function getUsers() {
  setTimeout(() => {
    let data = "用戶數據";
    console.log(data);
    iterator.next();
  }, 1000);
}
function getOrders() {
  setTimeout(() => {
    let data = "訂單數據";
    console.log(data);
    iterator.next();
  }, 1000);
}
function getGoods() {
  setTimeout(() => {
    let data = "商品數據";
    console.log(data);
  }, 1000);
}
function* gen() {
  yield getUsers();
  yield getOrders();
  yield getGoods();
}
// 調用生成器函數
let iterator = gen();
iterator.next();

輸出結果

 需求-2,補充調用傳參

function getUsers() {
  setTimeout(() => {
    let data = "用戶數據1";
    iterator.next(data);
  }, 1000);
}
function getOrders() {
  setTimeout(() => {
    let data = "訂單數據2";
    iterator.next(data);
  }, 1000);
}
function getGoods() {
  setTimeout(() => {
    let data = "商品數據3";
    iterator.next(data);
  }, 1000);
}
function* gen() {
  let users = yield getUsers();
  console.log(users);
  let orders = yield getOrders();
  console.log(orders);
  let goods = yield getGoods();
  console.log(goods);
}
// 調用生成器函數
let iterator = gen();
iterator.next();

輸出結果

1.13.1  Promise介紹與基本使用

Promise 是ES6引入的非同步編程的新解決方案。語法上 Promise 是一個構造函數用來封裝非同步操作並可以獲取其成功或失敗的結果。

  • Promise構造函數:Promise(excutor)
  • Promise.prototype.then 方法
  •  Promise.prototype.catch 方法
// 實例化 Promise 對象
const p = new Promise(function (resolve, reject) {
  setTimeout(() => {
    // let data = "讀取用戶數據";
    // resolve(data);
    let err = "讀取數據失敗!";
    reject(err);
  }, 1000);
});
// 調用 promise 對象的 then 方法
p.then(
  function (value) {
    console.log(value); // 讀取用戶數據
  },
  function (error) {
    console.error(error); // 讀取數據失敗!
  }
);

1.13.2  Promise封裝讀取文件

// 1、引入 fs 模塊
const fs = require("fs");
// 2、調用方法讀取文件
// fs.readFile('./resources/為學.md', (err, data) => {
//   // 如果失敗,則拋出錯誤
//   if (err) throw err;
//   // 如果沒有出錯,則輸出內容
//   console.log(data.toString());
// });
// 3、使用 Promise 封裝
const p = new Promise(function (resolve, reject) {
  fs.readFile("./resources/為學.md", (err, data) => {
    // 判斷如果失敗
    if (err) reject(err);
    // 如果成功
    resolve(data);
  });
});
p.then(function (value) {
  console.log(value.toString());
}, function (err) {
  console.log("讀取失敗!!")
})

輸出結果

1.13.3  Promise封裝AJAX請求

  • 方法-1  普通寫法
// 介面地址: https://api.apiopen.top/api/getDynamic
// 1、創建對象
const xhr = new XMLHttpRequest();
// 2、初始化
xhr.open("GET", "https://api.apiopen.top/api/getDynamic");
// 3、發送
xhr.send();
// 4、綁定事件,處理響應結果
xhr.onreadystatechange = function () {
  // 判斷
  if (xhr.readyState === 4) {
    // 判斷響應狀態碼 200-299
    if (xhr.status >= 200 && xhr.status < 300) {
      console.log(xhr.response);
    } else {
      // 如果失敗
      console.log(xhr.status);
    }
  }
};
  • 方法-2  Promise封裝
const p = new Promise((resolve, reject) => {
  // 1、創建對象
  const xhr = new XMLHttpRequest();
  // 2、初始化
  xhr.open("GET", "https://api.apiopen.top/api/getDynamic");
  // 3、發送
  xhr.send();
  // 4、綁定事件,處理響應結果
  xhr.onreadystatechange = function () {
    // 判斷
    if (xhr.readyState === 4) {
      // 判斷響應狀態碼 200-299
      if (xhr.status >= 200 && xhr.status < 300) {
        // 表示成功
        resolve(xhr.response);
      } else {
        // 如果失敗
        reject(xhr.status);
      }
    }
  };
});
// 指定回調
p.then(
  function (value) {
    console.log(value);
  },
  function (error) {
    console.log(error);
  }
);

1.13.4  Promise.prototype..then方法

// 創建 promise 對象
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("獲取用戶數據成功!");
  }, 1000);
});
// 調用 then 方法 then方法的返回結果是 Promise 對象,對象狀態由回調函數的執行結果決定
// 1、如果回調函數中返回的結果是 非 promise 類型的屬性, 狀態為成功,返回值為對象的成功的值
const result = p.then(
  (value) => {
    // console.log(value);
    // 1、非 promise 類型的屬性
    return "I Love You";
    // 2、是promise 對象
    // return new Promise((resolve, reject) => {
      // resolve("ok");
      // reject('error');
    // });
    // 3、拋出錯誤
    // throw new Error("出錯啦!");
    // throw '出錯啦!'
  },
  (reason) => {
    console.error(reason);
  }
);
console.log(result);
// p.then(
//   (value) => {
//     console.log(value);
//   },
//   (error) => {
//     console.log(error);
//   }
// );
// 鏈式調用
p.then(value=>{
}).then(reason=>{
})

1.13.5  Promise實踐練習-多個文件內容讀取

  • 方法-1  回調地獄
fs.readFile("./resources/為學.md", (err, data1) => {
  fs.readFile("./resources/插秧詩.md", (err, data2) => {
    fs.readFile("./resources/觀書有感.md", (err, data3) => {
      // let result = data1 + '\r\n' + data2 + '\r\n' + data3;
      let result = `${data1}\r\n${data2}\r\n${data3}`
      console.log(result);
    })
  })
});
  • 方法-2  使用 promise 實現
const p = new Promise((resolve, reject) => {
  fs.readFile("./resources/為學.md", (err, data) => {
    resolve(data);
  })
});
p.then(value => {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/插秧詩.md", (err, data) => {
      resolve([value, data]);
    })
  })
}).then(value => {
  return new Promise((resolve, reject) => {
    fs.readFile("./resources/觀書有感.md", (err, data) => {
      // 壓入
      value.push(data);
      resolve(value);
    });
  })
}).then(value => {
  console.log(value.join('\r\n'));
})
  • 方法-3  使用生成器函數
function one() {
  fs.readFile("./resources/為學.md", (err, data) => {
    iterator.next(data);
  })
}

              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 淺聊一下SpringMVC的核心組件以及通過源碼瞭解其執行流程 MVC作為WEB項目開發的核心環節,正如三個單詞的分解那樣,Controller(控制器)將View(視圖、用戶客戶端)與Model(javaBean:封裝數據)分開構成了MVC,今天我們淺聊一下SpringMVC的相關組件以及通過源碼... ...
  • 下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放: 項目介紹 為OLED屏幕開發I2C驅動 使用cuda編程加速視頻處理 這篇文章主要對項目的實現做整體的介紹, 包括硬體的需求, 最終實現的視頻播放效果, 以及軟體的實現思路. 1). 硬體需求 beaglebone ...
  • 對於有科班背景的讀者,可以跳過本系列文章。這些文章的主要目的是通過簡單易懂的彙總,幫助非科班出身的讀者理解底層知識,進一步瞭解為什麼在面試中會涉及這些底層問題。否則,某些概念將始終無法理解。這些電腦基礎文章將為你打通知識的任督二脈,祝你在編程領域中取得成功! ...
  • 下麵的系列文章記錄瞭如何使用一塊linux開發扳和一塊OLED屏幕實現視頻的播放: 項目介紹 為OLED屏幕開發I2C驅動 使用cuda編程加速視頻處理 這是此系列文章的第2篇, 主要總結和記錄一個I2C從設備的驅動, 在linux內核中如何實現, 如何給用戶態的程式暴露合適的介面, 讓用戶態有機會 ...
  • 1. 除非遇到異常情況,否則不需要調整配置 1.1. 不要“調優”伺服器,不要使用比率、公式或“調優腳本”作為設置配置變數的基礎 1.1.1. 在互聯網上搜索配置建議並不總是一個好主意,你會在博客、論壇等找到很多糟糕的建議 1.1.2. 很難判斷誰是真正的專家 1.1.3. 不要相信流行的記憶體消耗公 ...
  • Flink是一個分散式系統,要求有效地分配和管理計算資源以執行流式應用程式。它集成了所有常見的集群資源管理器,如Hadoop YARN和Kubernetes,但也可以設置為作為standalone甚至庫運行。 本節概述了Flink的體繫結構,並描述了其主要組件如何交互以執行應用程式以及從故障中恢復。 ...
  • 1. mysql資料庫四種常見資料庫引擎 1. MyISAM: MyISAM是MySQL最早的資料庫引擎之一。它被設計成處理大量的插入和查詢操作。MyISAM表格的數據存儲在三個文件上:.frm文件存儲表結構,.MYD文件存儲數據,.MYI文件存儲索引。MyISAM表格不支持事務處理和崩潰恢復,因此 ...
  • 隨著需求的不斷開發,前端項目不斷膨脹,業務提出:你們的首頁載入也太慢啦,我都需要7、8秒才能看到內容,於是乎主管就讓我聯合後端開啟優化專項,目標是3s內展示完全首頁的內容。 性能指標 開啟優化時,我們要清晰的知道現狀和目標,以及我們採用什麼樣的手段,通過檢測什麼指標來查看到優化的過程。 結果指標 根 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...