談到promise,首先你們應該瞭解promise的主要做用是解決異步加載的問題。promise
##關於異步異步
所謂"異步",簡單說就是一個任務不是連續完成的,能夠理解成該任務被人爲分紅兩段,先執行第一段,而後轉而執行其餘任務,等作好了準備,再回過頭執行第二段。async
好比,有一個任務是讀取文件進行處理,任務的第一段是向操做系統發出請求,要求讀取文件。而後,程序執行其餘任務,等到操做系統返回文件,再接着執行任務的第二段(處理文件)。這種不連續的執行,就叫作異步。函數
相應地,連續的執行就叫作同步。因爲是連續執行,不能插入其餘任務,因此操做系統從硬盤讀取文件的這段時間,程序只能乾等着。簡單的說同步就是你們排隊工做,異步就是你們同時工做。 ##Promise A+規範的 Promise 爲了便於理解,本文將分爲三個部分,每一個部分實現 Promise 的一部分特性,最終一步一步的實現一個完整的、遵循 promise A+ 規範的 Promise。Promise A+ 規範規定,Promise 有三種狀態,分別是 pending(默認狀態,表明等待)、fulfilled(表明成功)、rejected(表明失敗)。來看看 Promise 的用法,以及它有哪些特性。 var fn = new Promise(function (resolve, reject) {
// 異步操做
setTimeout(function() {
resolve('111')
// 因爲reslove和 reject 是互斥的,由於已經調用了 resolve,這裏reject不會執行 reject('111') }, 500) }) fn.then(function (data) { console.log('成功1:', data) return new Promise(function (resolve, reject) { reject('reject 02') } )}, function (err) { console.log('失敗1:', err) }) .then(function (data) { console.log('成功2:', data) }, function (err) { console.log('失敗2:', err) }).then(function (data) { console.log('成功2:', data)}, function (err) { console.log('失敗2:', err) })ui
1.Promise 類有 then 方法,then 方法有三個參數,分別是 Promise 成功和失敗的回調以及pending初始狀態this
2.Promise 支持鏈式調用,then 的返回值能夠是一個 Promise,也能夠是一個普通值,若是是 一個普通的值,那麼就會當作下一個 then 成功的回調函數的參數操作系統
3.Promis 還有其它擴展方法code
##接下來咱們簡單瞭解一下promise的一些封裝原理cdn
class Promise {
constructor(executor) { //定義初始狀態 this.status = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = [];//返回成功回調函數
let resolve = (data) => { // 加載數據判斷成功 if (this.status === 'pending') { this.value = data; this.status = 'resolved'; this.onResolvedCallbacks.forEach(fn => fn()); } } let reject = (reason) => { // 加載數據判斷失敗 if (this.status === 'pending') { this.reason = reason; this.status = 'rejected'; this.onRejectedCallbacks.forEach(fn => fn()); } }`對象
try { executor(resolve, reject); } catch (e) { reject(e); } }
then(onFulFilled, onRejected) { onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : y => y; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; }; let promise2; if (this.status === 'resolved') { promise2 = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); } if (this.status === 'rejected') { promise2 = new Promise((resolve, reject) => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e); } }, 0); }); } if (this.status === 'pending') { promise2 = new Promise((resolve, reject) => { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e); } }, 0) }); // 存放失敗的回調 this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); }) } return promise2; // 調用then後返回一個新的promise } // catch接收的參數 只用錯誤 catch(onRejected) { // catch就是then的沒有成功的簡寫 return this.then(null, onRejected); } }
Promise.resolve = function (val) { return new Promise((resolve, reject) => resolve(val)) }
Promise.reject = function (val) { return new Promise((resolve, reject) => reject(val)); }
瞭解了promise的原理,接下來給大家擴展一下promise番外篇,async-await函數和Generator 函數
1.Generator 函數
Genrator 函數要用* 來比標識,yield關鍵字表示暫停。將函數分割出好多個部分,調用一次next就會繼續向下執行。返回結果是一個迭代器,迭代器有一個next方法。
function* read() { console.log(1); let a = yield '123'; console.log(a); let b = yield 9 console.log(b); return b; } let it = read(); console.log(it.next('213')); // {value:'123',done:false} console.log(it.next('100')); // {value:9,done:false} console.log(it.next('200')); // {value:200,done:true} console.log(it.next('200')); // {value:200,done:true}
yield後面跟着的是value的值,yield等號前面的是咱們當前調用next傳進來的值,而且第一次next傳值是無效的。
處理異步的時候Generator和Promise搭配使用
let bluebird = require('bluebird'); let fs = require('fs'); let read = bluebird.promisify(fs.readFile);//將readFile轉爲Promise對象的實例 function* r() { let content1 = yield read('./2.promise/1.txt', 'utf8'); let content2 = yield read(content1, 'utf8'); return content2; }
2.async-await函數
let bluebird = require('bluebird'); let fs = require('fs'); let read = bluebird.promisify(fs.readFile);
async function r(){ try{ let content1 = await read('./2.promise/100.txt','utf8'); let content2 = await read(content1,'utf8'); return content2; }catch(e){ // 若是出錯會catch console.log('err',e) } }
以上是我對promise的理解,但願有什麼錯誤能夠指正。