問題需求
封裝讀取檔案的方法(讀取檔案為異步操作),不用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概念
- Promise 是一個 建構式,既然是建構式, 那么,我們就可以 new Promise() 得到一個 Promise 的實體;
- 在 Promise 上,有兩個函式,分別叫做 resolve(成功之后的回呼函式) 和 reject(失敗之后的回呼函式)
- 在 Promise 建構式的 Prototype 屬性上,有一個 .then() 方法,也就說,只要是 Promise 建構式創建的實體,都可以訪問到 .then() 方法
- Promise 表示一個 異步操作;每當我們 new 一個 Promise 的實體,這個實體,就表示一個具體的異步操作;
- 既然 Promise 創建的實體,是一個異步操作,那么,這個 異步操作的結果,只能有兩種狀態:
5.1 狀態1: 異步執行成功了,需要在內部呼叫 成功的回呼函式 resolve 把結果回傳給呼叫者;
5.2 狀態2: 異步執行失敗了,需要在內部呼叫 失敗的回呼函式 reject 把結果回傳給呼叫者;
5.3 由于 Promise 的實體,是一個異步操作,所以,內部拿到 操作的結果后,無法使用 return 把操作的結果回傳給呼叫者; 這時候,只能使用回呼函式的形式,來把 成功 或 失敗的結果,回傳給呼叫者; - 我們可以在 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="https://www.cnblogs.com/ygjzs/p/è?·??–??°???" id="btn">
<script src="https://www.cnblogs.com/ygjzs/p/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
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/162728.html
標籤:JavaScript
下一篇:vue-vuex
