promise這個東西,我都不知道見過多少回了!,非常重要,這裡在回憶一遍 發現問題 使用promise 封裝promise html頁面中promise 處理錯誤 最後 這種事把錯誤放在最後處理 當然,也可以在中間處理錯誤 不過一般都在最後處理 promise resolve不支持多參數 ...
promise這個東西,我都不知道見過多少回了!,非常重要,這裡在回憶一遍
發現問題
const fs = require('fs')
fs.readFile('./data/1.txt', (err, data) => {
console.log(111)
fs.readFile('./data/2.txt', (err, data) => {
console.log(222)
fs.readFile('./data/3.txt', (err, data) => {
console.log(333)
})
})
})
// Promise
使用promise
/**
* Promise 在 Ecmascript 6 中體現出來就是一個對象
* Promise 是一個容器
* 一般用來封裝一個非同步操作
* 非同步操作是一個無法預測的事情,要嗎成功,要嗎失敗
* 容器內部有三種狀態:
* pending 正在處理
* resolved 成功,已解決
* rejected 駁回,失敗
*/
const fs = require('fs')
// Promise 對象一經創建,立即執行
new Promise((resolve, reject) => {
fs.readFile('./data/2.txt', (err, data) => {
if (err) {
// 當 Promise 對象內部的非同步操作結果失敗的時候,告訴 Promise 對象容器,該非同步任務失敗了
// 其實就是將 Promise 內部的 Pending 狀態改為 Rejected
reject(err)
}
// 當代碼執行到這裡,說明該 Promise 對象內部的非同步操作沒有錯誤發生,證明成功了
// 然後在這裡將 Promise 內部的 Pending 狀態改為 Resolved
resolve(data)
})
})
// Promise 實例對象有一個方法:then 方法
// then 需要傳遞兩個回調處理函數
// 其中第一個回調處理函數就是 Promise 對象內部的 resolve 函數
// 第二個回調處理函數是可選的,如果傳遞則就是 Promise 對象內部的 reject 函數
.then((data) => {
console.log(111)
console.log(data.toString())
return new Promise((resolve, reject) => {
fs.readFile('./data/3.txt', (err, data) => {
if (err) {
// 這裡沒有使用 return 的原因就是 Promise 的狀態只能從 Pending 變為 Resolve 或者 Rejected
// 狀態一旦改變,就不會再發生變化
reject(err)
}
resolve(data)
})
})
}, (err) => {
console.log('讀取文件失敗了')
})
// then 方法之後可以繼續鏈式調用 then
// 後續的每一個 then 中指定的回調處理函數都會被執行
// 後續的 then 中指定的回調處理函數可以接收上一個 then 中指定的成功的回調處理函數的返回結果
// 1. 沒有返回值,預設就是 undefined
// 2. 有普通的返回值,數字、字元串、對象、數組。。。
// 3. 返回一個新的 Promise 對象
.then((data) => {
console.log(222)
console.log(data.toString())
return new Promise((resolve, reject) => {
fs.readFile('./data/1.txt', (err, data) => {
if (err) {
// 這裡沒有使用 return 的原因就是 Promise 的狀態只能從 Pending 變為 Resolve 或者 Rejected
// 狀態一旦改變,就不會再發生變化
reject(err)
}
resolve(data)
})
})
})
.then((data) => {
console.log(333)
// 二進位數據調用 toString() 方法可以轉換為普通的字元,預設就是 utf8 編碼
console.log(data.toString())
})
封裝promise
const fs = require('fs')
readFile('./data/1.txt', 'utf8')
.then(data => {
console.log(data)
return readFile('./data/2.txt', 'utf8')
})
.then(data => {
console.log(data)
return readFile('./data/3.txt', 'utf8')
})
.then(data => {
console.log(data)
})
function readFile(...args) {
return new Promise((resolve, reject) => {
fs.readFile(...args, (err, data) => {
if (err) {
reject(err)
}
resolve(data)
})
})
}
html頁面中promise
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XMLHttpRequest - Promise</title>
</head>
<body>
<div>
姓名:
年齡:
</div>
<script>
function xhr(options) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open(options.type || 'get', options.url)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
resolve(xhr.responseText)
} else {
reject()
}
}
xhr.send()
})
}
xhr({
url: '',
type: '',
data: ''
})
.then(data => {
return xhr({
})
})
.then(data => {
// 做渲染處理
})
$.ajax({
}).then(data => {
return $.ajax({
})
})
.then(data => {
})
</script>
</body>
</html>
處理錯誤--最後
這種事把錯誤放在最後處理
當然,也可以在中間處理錯誤
不過一般都在最後處理
const fs = require('fs')
readFile('./data/4.txt', 'utf8')
.then(data => {
console.log(data)
return readFile('./data/2.txt', 'utf8')
})
.then(data => {
console.log(data)
JSON.parse('{dsadsa')
return readFile('./data/3.txt', 'utf8')
})
.then(data => {
console.log(data)
})
// 在使用 Promise 做非同步流程式控制制的時候,關於異常的處理可以通過在最後一個 then 之後設置一個 catch
// 然後指定一個失敗處理函數
// 該函數可以捕獲前面所有的 Promise 對象本身以及 then 內部的任務錯誤
// 當前面任何一個發生異常,直接進入 catch,後續所有的 Promise 包括 then 不再執行
.catch(err => {
console.log(err)
})
function readFile(...args) {
return new Promise((resolve, reject) => {
fs.readFile(...args, (err, data) => {
if (err) {
reject(err)
}
resolve(data)
})
})
}
promise-resolve不支持多參數