JavaScript-promise

来源:https://www.cnblogs.com/ygjzs/archive/2019/12/15/12042098.html
-Advertisement-
Play Games

問題需求 封裝讀取文件的方法(讀取文件為非同步操作),不用es6 回調地獄 對上面代碼進行改進 promise概念 1. Promise 是一個 構造函數,既然是構造函數, 那麼,我們就可以 new Promise() 得到一個 Promise 的實例; 2. 在 Promise 上,有兩個函數,分別 ...


問題需求

封裝讀取文件的方法(讀取文件為非同步操作),不用es6

// 需求:你要封裝一個方法,我給你一個要讀取文件的路徑,你這個方法能幫我讀取文件,並把內容返回給我

const fs = require('fs')
const path = require('path')

// 這是普通讀取文件的方式
/* fs.readFile(path.join(__dirname, './files/1.txt'), 'utf-8', (err, dataStr) => {
  if (err) throw err
  console.log(dataStr)
}) */

// 初衷: 給定文件路徑,返回讀取到的內容
// 我們可以規定一下, callback 中,有兩個參數,第一個參數,是 失敗的結果;第二個參數是成功的結果;
// 同時,我們規定了: 如果成功後,返回的結果,應該位於 callback 參數的第二個位置,此時, 第一個位置 由於沒有出錯,所以,放一個 null;  如果失敗了,則 第一個位置放 Error對象,第二個位置防止一個 undefined
function getFileByPath(fpath, callback) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    // 如果報錯了,進入if分支後,if後面的代碼就沒有必要執行了
    if (err) return callback(err)
    // console.log(dataStr)
    // return dataStr
    callback(null, dataStr)
  })
}

/* var result = getFileByPath(path.join(__dirname, './files/1.txt'))
console.log(result) */
getFileByPath(path.join(__dirname, './files/1.txt'), (err, dataStr) => {
  // console.log(dataStr + '-----')
  if (err) return console.log(err.message)
  console.log(dataStr)
})

回調地獄

對上面代碼進行改進

// 需求:你要封裝一個方法,我給你一個要讀取文件的路徑,你這個方法能幫我讀取文件,並把內容返回給我

const fs = require('fs')
const path = require('path')


function getFileByPath(fpath, succCb, errCb) {
  fs.readFile(fpath, 'utf-8', (err, dataStr) => {
    if (err) return errCb(err)
    succCb(dataStr)
  })
}

// getFileByPath(path.join(__dirname, './files/11.txt'), function (data) {
//   console.log(data + '娃哈哈,成功了!!!')
// }, function (err) {
//   console.log('失敗的結果,我們使用失敗的回調處理了一下:' + err.message)
// })

// 需求: 先讀取文件1,再讀取文件2,最後再讀取文件3
// 回調地獄
// 使用 ES6 中的 Promise,來解決 回調地獄的問題;
// 問: Promise 的本質是要乾什麼的:就是單純的為瞭解決回調地獄問題;並不能幫我們減少代碼量;
getFileByPath(path.join(__dirname, './files/1.txt'), function (data) {
  console.log(data)

  getFileByPath(path.join(__dirname, './files/2.txt'), function (data) {
    console.log(data)

    getFileByPath(path.join(__dirname, './files/3.txt'), function (data) {
      console.log(data)
    })
  })
})

promise概念

  1. Promise 是一個 構造函數,既然是構造函數, 那麼,我們就可以 new Promise() 得到一個 Promise 的實例;
  2. 在 Promise 上,有兩個函數,分別叫做 resolve(成功之後的回調函數) 和 reject(失敗之後的回調函數)
  3. 在 Promise 構造函數的 Prototype 屬性上,有一個 .then() 方法,也就說,只要是 Promise 構造函數創建的實例,都可以訪問到 .then() 方法
  4. Promise 表示一個 非同步操作;每當我們 new 一個 Promise 的實例,這個實例,就表示一個具體的非同步操作;
  5. 既然 Promise 創建的實例,是一個非同步操作,那麼,這個 非同步操作的結果,只能有兩種狀態:
    5.1 狀態1: 非同步執行成功了,需要在內部調用 成功的回調函數 resolve 把結果返回給調用者;
    5.2 狀態2: 非同步執行失敗了,需要在內部調用 失敗的回調函數 reject 把結果返回給調用者;
    5.3 由於 Promise 的實例,是一個非同步操作,所以,內部拿到 操作的結果後,無法使用 return 把操作的結果返回給調用者; 這時候,只能使用回調函數的形式,來把 成功 或 失敗的結果,返回給調用者;
  6. 我們可以在 new 出來的 Promise 實例上,調用 .then() 方法,【預先】 為 這個 Promise 非同步操作,指定 成功(resolve) 和 失敗(reject) 回調函數;

註意:這裡 new 出來的 promise, 只是代表 【形式上】的一個非同步操作;
什麼是形式上的非同步操作:就是說,我們只知道它是一個非同步操作,但是做什麼具體的非同步事情,目前還不清楚
var promise = new Promise()

const fs = require('fs')

// 每當 new 一個 Promise 實例的時候,就會立即 執行這個 非同步操作中的代碼
// 也就是說,new 的時候,除了能夠得到 一個 promise 實例之外,還會立即調用 我們為 Promise 構造函數傳遞的那個 function,執行這個 function 中的 非同步操作代碼;
/* var promise = new Promise(function () {
  fs.readFile('./files/2.txt', 'utf-8', (err, dataStr) => {
    if (err) throw err
    console.log(dataStr)
  })
}) */


// 初衷: 給路徑,返回讀取到的內容
function getFileByPath(fpath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {

      if (err) return reject(err)
      resolve(dataStr)

    })
  })
}

使用promise解決回調地獄

兩種情況:

會中斷

const fs = require('fs')

function getFileByPath(fpath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {

      if (err) return reject(err)
      resolve(dataStr)

    })
  })
}

// 讀取文件1
// 在上一個 .then 中,返回一個新的 promise 實例,可以繼續用下一個 .then 來處理


// 如果 ,前面的 Promise 執行失敗,我們不想讓後續的Promise 操作被終止,可以為 每個 promise 指定 失敗的回調
 getFileByPath('./files/11.txt')
  .then(function (data) {
    console.log(data)

    // 讀取文件2
    return getFileByPath('./files/2.txt')
  }, function (err) {
    console.log('這是失敗的結果:' + err.message)
    // return 一個 新的 Promise
    return getFileByPath('./files/2.txt')
  })
  .then(function (data) {
    console.log(data)

    return getFileByPath('./files/3.txt')
  })
  .then(function (data) {
    console.log(data)
  }).then(function (data) {
    console.log(data)
  }) 

不會中斷

const fs = require('fs')

function getFileByPath(fpath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fpath, 'utf-8', (err, dataStr) => {

      if (err) return reject(err)
      resolve(dataStr)

    })
  })
}

// 當 我們有這樣的需求: 哪怕前面的 Promise 執行失敗了,但是,不要影響後續 promise 的正常執行,此時,我們可以單獨為 每個 promise,通過 .then 指定一下失敗的回調;

// 有時候,我們有這樣的需求,個上面的需求剛好相反:如果 後續的Promise 執行,依賴於 前面 Promise 執行的結果,如果前面的失敗了,則後面的就沒有繼續執行下去的意義了,此時,我們想要實現,一旦有報錯,則立即終止所有 Promise的執行;

getFileByPath('./files/1.txt')
  .then(function (data) {
    console.log(data)

    // 讀取文件2
    return getFileByPath('./files/22.txt')
  })
  .then(function (data) {
    console.log(data)

    return getFileByPath('./files/3.txt')
  })
  .then(function (data) {
    console.log(data)
  })
  .catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 執行失敗,則立即終止所有 promise 的執行,並 馬上進入 catch 去處理 Promise中 拋出的異常;
    console.log('這是自己的處理方式:' + err.message)
  })

jquery中使用promise

想不到jQuery這個強大的庫中竟然支持promise,果然強大

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>

  <input type="button" value="获�数�" id="btn">

  <script src="./node_modules/jquery/dist/jquery.min.js"></script>

  <script>
    $(function () {
      $('#btn').on('click', function () {
        $.ajax({
          url: './data.json',
          type: 'get',
          dataType: 'json'
        })
          .then(function (data) {
            console.log(data)
          })
      })
    });
  </script>
</body>

</html>
{
  "name": "小強",
  "age": 18
}

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

-Advertisement-
Play Games
更多相關文章
  • 首發於微信公眾號《前端成長記》,寫於 2019.12.15 背景 本文記錄刷題過程中的整個思考過程,以供參考。主要內容涵蓋: 題目分析設想 編寫代碼驗證 查閱他人解法 思考總結 目錄 "110.平衡二叉樹" "111.二叉樹的最小深度" "112.路徑總和" "118.楊輝三角" "119.楊輝三角 ...
  • vue 完整代碼 這是一個完整的vue案例,但是介面似乎都失效了,單是代碼本身還是很有參考價值的呦!~ 裡面包含了:vue,vue router,。。。。,還是直接看json文件吧 都用到了這些技術,嘿嘿嘿 所以來說還是很值得一看的,如果會寫介面的話,還可以自己寫一個介面代替上去 OK,接下來就是就 ...
  • order order 屬性 設置或檢索彈性盒模型對象的子元素出現的順序。。 註意:如果元素不是彈性盒對象的元素,則 order 屬性不起作用。 "詳解查看官方解釋" ...
  • 大家好,我是Dotnet9小編,一個從事dotnet開發8年+的程式員。本文介紹WordPress主題JustNews,本站Dotnet9既是使用WordPress + JustNews主題搭建而成的。 WordPress是世界上流行的建站程式,英文世界中有超過10,000個WordPress主題, ...
  • 伸縮佈局 參考鏈接:https://developer.mozilla.org/zh CN/docs/Web/CSS/flex 以前在網頁開發過程中,佈局一直是不可或缺的,從最早的表格佈局,到後來的DIV+CSS佈局,現在再到CSS3的伸縮佈局。 CSS3在佈局方面做了非常大的改進,使得我們對塊級元 ...
  • 正則表達式是構成搜索模式的字元序列。 該搜索模式可用於文本搜索和文本替換操作。 什麼是正則表達式? 正則表達式是構成搜索模式(search pattern)的字元序列。 當您搜索文本中的數據時,您可使用搜索模式來描述您搜索的內容。 正則表達式可以是單字元,或者更複雜的模式。 正則表達式可用於執行所有 ...
  • vue resource moment preview 縮略圖使用實例 圖片懶載入(muit提供) ...
  • vuex "vuex官方文檔" app.vue amount.vue counter.vue ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...