Es6中的promise解決callback hell回撥地獄問題及示例程式碼
1.js中多個非同步呼叫(介面,讀取檔案)時沒有順序,若業務現在要求有順序的呼叫,就只能巢狀回撥,如果巢狀回撥3個以下程式碼量還不是很多,還可以湊乎,超過3個後重復程式碼多,可維護性差,程式碼醜陋ugly,就造成了callback hell,所以Es6出了promise解決此問題,jquery支援promise功能,node中的mongoose支援。
使用場景:註冊功能前查詢使用者名稱字是否存在,手機號是否存在等等,頁面的select多級聯動(查詢省市縣)下拉框選擇後還需要查詢資料。
示例程式碼:
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('讀取失敗')
// 丟擲異常
// 1. 阻止程式的執行
// 2. 把錯誤訊息列印到控制檯
throw err
}
console.log(data)
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('讀取失敗')
// 丟擲異常
// 1. 阻止程式的執行
// 2. 把錯誤訊息列印到控制檯
throw err
}
console.log(data)
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
// return console.log('讀取失敗')
// 丟擲異常
// 1. 阻止程式的執行
// 2. 把錯誤訊息列印到控制檯
throw err
}
console.log(data)
})
})
})
promise容器概念:pending正在進行後有2種狀態,要麼成功變成resolved,要麼失敗變成rejected.
promiseAPI程式碼圖示:
promise的鏈式呼叫
1.示例程式碼:
1)使用promise未封裝url版本
var fs = require('fs')
var p1 = new Promise(function (resolve, reject) {
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p2 = new Promise(function (resolve, reject) {
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p3 = new Promise(function (resolve, reject) {
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
p1
.then(function (data) {
console.log(data)
// 當 p1 讀取成功的時候
// 當前函式中 return 的結果就可以在後面的 then 中 function 接收到
// 當你 return 123 後面就接收到 123
// return 'hello' 後面就接收到 'hello'
// 沒有 return 後面收到的就是 undefined
// 上面那些 return 的資料沒什麼卵用
// 真正有用的是:我們可以 return 一個 Promise 物件
// 當 return 一個 Promise 物件的時候,後續的 then 中的 方法的第一個引數會作為 p2 的 resolve
//
return p2
}, function (err) {
console.log('讀取檔案失敗了', err)
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
console.log('end')
})
2)使用promise封裝url後版本
var fs = require('fs')
function pReadFile(filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
pReadFile('./data/a.txt')
.then(function (data) {
console.log(data)
return pReadFile('./data/b.txt')
})
.then(function (data) {
console.log(data)
return pReadFile('./data/c.txt')
})
.then(function (data) {
console.log(data)
})