>[danger]什么是Promise
1. 它是異步操作的一個解決方案, 簡單說它就是一個異步操作的容器, 在未來某一個時刻會完成的操作
2. Promise是一個構造函數, 它身上有resolve和reject方法, 原型上有then和catch方法
3. 它只有三種狀態, pending(運行中) fulfilled(成功), rejected(失敗)
*******
擴展:
1. Ajax請求回調太多, 形成回調地獄, 可以配合Promise替代回調函數, 但是Promise本身又是鏈式調用then, 會形成很多的鏈式回調, 代碼也不太方便閱讀
2. 我們可以使用ES7中的Async+Await把請求變為同步請求.
3. 每次調用then, 會返回一個新的Promise對象, 而且return的值會作為下一次then的參數
4. then() 接收resolve / catch() 接收reject / finally 無論如何都執行
*******
>[danger]Promise.all()
---
用于把多個Promise對象, 合并成一個, 如何有一個失敗, 直接進入catch, 如果子Promise自己實現了catch, 則合并的Promise對象不會進入catch, 進入then
~~~
Promise.all([p1, p2, p3]);
~~~
>[danger]Promise.resolve()
---
用于將對象轉成Promise對象
~~~javascript
Promise.resolve('foo') // 返回一個Promise對象
// 等價于
new Promise(resolve => resolve('foo'))
~~~
>[danger]手寫Promise實現
1. Promise雛形, 先理解這個
```
// 1. 聲明Promise, fn就是你在new Promise傳入的方法體
function Promise(fn) {
var value = null;
var callbacks = []; //callbacks為數組,因為可能同時有很多個回調
// 接收外面.then時傳入進來的回調函數
this.then = function (onFulfilled) {
// 加入到callbacks數組中
callbacks.push(onFulfilled);
};
// 當promise內部調用resolve方法時, 將.then傳入進來的回調函數全部執行一遍
function resolve(value) {
callbacks.forEach(function (callback) {
callback(value); // 把value值帶出去, 帶到then注冊的方法參數中
});
}
fn(resolve); // 調用new Promise時, 傳入的方法體, 開始執行了
}
```
2. 調用promise時, 發現resolve方法馬上同步執行了, 所以還沒等then調用呢.
```
function getUserId() {
return new Promise(function (resolve) {
resolve(9876);
});
}
// 2. 調用方法, 得到Promise對象. 調用then注冊回調函數
getUserId().then(function (id) {
console.log(id); // 我們發現什么也沒有打印, 證明resolve先執行了, 而then還沒調用.所以這里沒有回調成功
});
```
3. 讓resolve里等待主線程執行完畢它再執行, 改裝代碼
```
function reso(value) {
setTimeout(function(){
callbacks.forEach(function (callback) {
callback(value); // 把value值帶出去, 帶到then注冊的方法參數中
});
}, 0);
}
```
4. 如果失敗的話怎么處理呢? (最簡單, 最終版, 還不能實現太復雜功能)
```
// 1. 聲明Promise, fn就是你在new Promise傳入的方法體
function Promise(fn) {
var value = null;
var callbacks = []; //callbacks為數組,因為可能同時有很多個回調
// 接收外面.then時傳入進來的回調函數
this.then = function (onFulfilled, onRejected) {
// 加入到callbacks數組中 (注意這里分成功, 失敗情況)
callbacks.push({
"onFulfilled": onFulfilled,
"onRejected": onRejected
});
};
// 當promise內部調用resolve方法時, 將.then傳入進來的回調函數全部執行一遍
function resolve(value) {
execute("onFulfilled", value);
}
function reject(value) {
execute("onRejected", value);
}
function execute(key, value) {
setTimeout(function () {
callbacks.forEach(function (callbackObj) {
callbackObj[key](value); // 把value值帶出去, 帶到then注冊的方法參數中
});
}, 0);
}
fn(resolve, reject); // 調用new Promise時, 傳入的方法體, 開始執行了
}
function getUserId() {
return new Promise(function (resolve, reject) {
resolve(9876);
setTimeout(function () {
reject("失敗");
}, 2000);
});
}
getUserId().then(function (id) {
console.log(id);
}, function (err) {
console.log(err);
})
```
- web前端
- CSS問題
- 布局
- 雙飛翼布局_flex方式
- 雙飛翼布局_margin方式
- 圣杯布局_flex方式
- 圣杯布局_margin方式
- 子元素居中問題
- 彈性布局
- 概念_
- 標準模式與混雜模式
- 各種FC
- line-height
- vertical-align
- CSS3新特性
- 效果
- div添加箭頭
- CSS繪制三角形
- JavaScript
- 兼容
- 事件相關
- 原理
- Ajax原理
- 繼承原理
- 原型鏈繼承
- 組合繼承
- 寄生組合繼承
- 數據綁定
- 1單向數據綁定m到c到v
- 2偽雙向數據綁定
- 3雙向數據綁定
- socket.io
- 運行時
- this指向
- 0.1+0.2問題
- 對象/數組-深拷貝&淺拷貝
- 事件循環
- typeof
- instanceof
- 概念
- 閉包
- 回調函數
- Promise
- 原生對象
- Attribute和property區別
- 防抖函數
- 節流函數
- 語言類型
- Vue
- Vue優缺點
- 仿Vue源碼
- 1數據綁定_Observe
- 2數據綁定_訂閱者&觀察者定義
- 3數據綁定_Vue類實現
- 4數據綁定_Vue訪問data更改
- 5DOM編譯_Compile_雙大括號模板講解
- 6DOM編譯_v-model講解
- 7DOM編譯_v-on:事件綁定講解
- 項目總結
- 使用Svg圖標
- vueCli環境_真機測試
- vueCli集成環信SDK
- 父子組件雙向綁定
- React
- React優缺點
- 我的組件庫
- Vue的組件庫
- 環信_聊天組件
- 面試題
- HTML_分類
- CSS_分類
- JavaScript_分類
- VueJS_分類
- ReactJS_分類
- AngularJS_分類
- 瀏覽器端
- 筆試題
- CSS
- 特殊布局
- JavaScript_
- 經典_宏任務_微任務
- 瀏覽器問題
- CORS
- web服務器
- Apache
- 開啟跨域
- Nginx
- 常用命令
- 正向代理
- 反向代理
- 負載均衡
- mac安裝Nginx
- 配置80端口
- 算法
- 冒泡排序
- 選擇排序
- 合并對象_排序
- 楊輝三角
- 紅黑樹
- 計算機基礎
- 網絡相關
- OSI七層模型
- http協議
- http工作原理
- https協議
- GET和POST區別
- hosts文件
- php相關
- session機制
- Linux
- 阿里云服務器
- linux使用Mysql
- 安裝mysql
- 導入.sql文件
- 遠程連接mysql
- linux使用xampp
- 安裝Xampp
- 配置web訪問
- 域名綁定服務器
- linux搭建git服務器_apache下
- 代碼管理
- 什么是git
- 命令行_使用git
- .gitignore文件講解
- 軟件
- VSCode的安裝
- 理財
- 基金
- 攝影