日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

    歡迎訪問 生活随笔!

    生活随笔

    當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

    编程问答

    promise是什么?简单分析promise原理

    發布時間:2024/4/14 编程问答 31 豆豆
    生活随笔 收集整理的這篇文章主要介紹了 promise是什么?简单分析promise原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

    預備知識

    • 回調函數
    • 高級函數
    • 發布-訂閱模式
    • promise A+ 規范

    promise是什么,能干什么

    Promise是異步編程的一種解決方案,它可以解決異步回調地獄的問題,防止層層嵌套對程序代碼帶來的難維護性。既然帶來了方便,我們就有必要學習它的原理以及底層實現,所以筆者就按照PromiseA+規范寫了一個簡單的Promise,并實現了Promise.all(),Promise.race()等API

    • 解決回調地獄
    • 解決多個回調函數同步結果

    promise的幾個方法

    • promise.all()
    • promise.race()
    • promise.resolve()
    • promise.reject()

    promise的三種狀態

    • 等待態 pending
    • 成功態 resolved
    • 失敗態 rejected

    promise的特點

    • 1.executor 默認時new的時候就自動執行
    • 2.每個promise的實例 都有then方法
    • 3.then方法中有兩個參數 分別是成功的回調和失敗的回調
    • 4.then方法是異步的(微任務) // 微任務先于宏任務執行
    • 5.同一個promise的實例可以then多次,成功時回調用所有的成功方法,失敗時會調用所有的失敗方法
    • 6.new Promise中可以支持異步行為
    • 7.如果發現錯誤就會走入失敗態

    下一次的輸入需要上一次的輸出 (有依賴關系)

    • 1.如果一個promise執行完后 返回的還是一個promise,會把這個promise 的執行結果,傳遞給下一次then中
    • 2.如果then中返回的不是promise 是一個普通值,會將這個普通值作為下次then的成功的結果
    • 3.如果當前then中失敗了 會走下一個then的失敗
    • 4.如果返回的是undefined 不管當前是成功還是失敗 都會走下一次的成功
    • 5.catch是錯誤沒有處理的情況下才會走
    • 6.then中可以不寫東西,相當于白寫 (值的穿透)

    promise A+ 規范

    • 原文
    • 翻譯
    • 校驗插件 npm install promises-aplus-tests -g 用于檢查自己寫的promise是否符合promise規范

    簡單實現 待完善

    function Promise(executor){let self = this;self.value = undefined; // 成功時的參數self.reason = undefined; // 失敗時的參數self.status = 'pending'; // 狀態 self.onResolvedCallbacks = [];// 存放then中成功的回調 self.onRejectedCallbacks = []; // 存放then中失敗的回調 function resolve(value){ // if(self.status === 'pending'){self.value = value;self.status = 'resolved';self.onResolvedCallbacks.forEach(fn=>fn());}}function reject(reason){if(self.status === 'pending'){self.reason = reason;self.status = 'rejected';self.onRejectedCallbacks.forEach(fn=>fn());}}// 如果函數執行時發生異常 就走到失敗中try{executor(resolve,reject);}catch(e){reject(e);} } Promise.prototype.then = function(onFulfilled,onRejected){let self = this;if(self.status === 'resolved'){onFulfilled(self.value);}if(self.status === 'rejected'){onRejected(self.reason);}if(self.status === 'pending'){// 保存回調函數self.onResolvedCallbacks.push(()=>{onFulfilled(self.value);});self.onRejectedCallbacks.push(()=>{onRejected(self.reason)});} } module.exports = Promise; 復制代碼

    基本實現

    function Promise(executor) {let self = this;self.value = undefined; // 成功的值self.reason = undefined; // 失敗的原因self.status = 'pending'; // 值是pending狀態self.onResolvedCallbacks = []; // 可能new Promise的時候會有異步操作,保存成功和失敗的回調 self.onRejectedCallbacks = [];function resolve(value) { // 把狀態改成成功態if (self.status === 'pending') { // 只有等待態 可以改變狀態self.value = value;self.status = 'resolved';self.onResolvedCallbacks.forEach(fn => fn());}}function reject(reason) { // 把狀態改成失敗態if (self.status === 'pending') {self.reason = reason;self.status = 'rejected';self.onRejectedCallbacks.forEach(fn => fn());}}try {// 默認new Promise時 應該執行對應的執行器(同步執行)executor(resolve, reject);} catch (e) { // 如果執行exectuor時 發生錯誤 就會讓當前的promise變成失敗態reject(e);} } /*** * @param {*} promise2 then的返回值 (返回的新的promise)* @param {*} x then中成功或者失敗函數的返回值* @param {*} resolve promise2的resolve* @param {*} reject promise2的reject*/ // 所有的promise都遵循這個規范 (所有的promise可以通用)function resolvePromise(promise2,x,resolve,reject){// promise2和函數執行后返回的結果是同一個對象if(promise2 === x){ return reject(new TypeError('Chaining cycle'));}let called;// x可能是一個promise 或者是一個普通值if(x!==null && (typeof x=== 'object' || typeof x === 'function')){try{let then = x.then; // 取對象上的屬性 怎么能報異常呢?(這個promise不一定是自己寫的 可能是別人寫的 有的人會亂寫)// x可能還是一個promise 那么就讓這個promise執行即可// {then:{}}// 這里的邏輯不單單是自己的 還有別人的 別人的promise 可能既會調用成功 也會調用失敗if(typeof then === 'function'){then.call(x,y=>{ // 返回promise后的成功結果// 遞歸直到解析成普通值為止if(called) return; // 防止多次調用called = true;// 遞歸 可能成功后的結果是一個promise 那就要循環的去解析resolvePromise(promise2,y,resolve,reject);},err=>{ // promise的失敗結果if(called) return;called = true;reject(err);});}else{resolve(x);}}catch(e){if(called) return;called = true;reject(e);}}else{ // 如果x是一個常量resolve(x);} } // then調用的時候 都是異步調用 (原生的then的成功或者失敗 是一個微任務) Promise.prototype.then = function (onFulfilled, onRejected) {// 成功和失敗的回調 是可選參數// onFulfilled成功的回調 onRejected失敗的回調let self = this;let promise2;// 需要沒次調用then時都返回一個新的promisepromise2 = new Promise((resolve, reject) => {if (self.status === 'resolved') {setTimeout(()=>{try {// 當執行成功回調的時候 可能會出現異常,那就用這個異常作為promise2的錯誤的結果let x = onFulfilled(self.value);//執行完當前成功回調后返回結果可能是promiseresolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)}if (self.status === 'rejected') {setTimeout(()=>{try {let x = onRejected(self.reason);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)}if (self.status === 'pending') {self.onResolvedCallbacks.push(() => {setTimeout(()=>{try {let x = onFulfilled(self.value);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)});self.onRejectedCallbacks.push(() => {setTimeout(()=>{try {let x = onRejected(self.reason);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)});}});return promise2 } // 為什么加setTimeout (規范要求的)Promise.defer = Promise.deferred = function(){let dfd = {};dfd.promise = new Promise((resolve,reject)=>{dfd.resolve = resolve;dfd.reject = reject;})return dfd; } module.exports = Promise; 復制代碼

    最終版本

    function Promise(executor) {let self = this;self.value = undefined; self.reason = undefined; self.status = 'pending';self.onResolvedCallbacks = [];self.onRejectedCallbacks = [];function resolve(value) { if (self.status === 'pending') {self.value = value;self.status = 'resolved';self.onResolvedCallbacks.forEach(fn => fn());}}function reject(reason) { if (self.status === 'pending') {self.reason = reason;self.status = 'rejected';self.onRejectedCallbacks.forEach(fn => fn());}}try {executor(resolve, reject);} catch (e) { reject(e);} } function resolvePromise(promise2,x,resolve,reject){if(promise2 === x){return reject(new TypeError('Chaining cycle'));}let called;if(x!==null && (typeof x=== 'object' || typeof x === 'function')){try{let then = x.then; if(typeof then === 'function'){then.call(x,y=>{ if(called) return; called = true;resolvePromise(promise2,y,resolve,reject);},err=>{ if(called) return;called = true;reject(err);});}else{resolve(x);}}catch(e){if(called) return;called = true;reject(e);}}else{ // 如果x是一個常量resolve(x);} } Promise.prototype.then = function (onFulfilled, onRejected) {onFulfilled = typeof onFulfilled === 'function'?onFulfilled:val=>val;onRejected = typeof onRejected === 'function'?onRejected: err=>{throw err}let self = this;let promise2;promise2 = new Promise((resolve, reject) => {if (self.status === 'resolved') {setTimeout(()=>{try {let x = onFulfilled(self.value);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)}if (self.status === 'rejected') {setTimeout(()=>{try {let x = onRejected(self.reason);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)}if (self.status === 'pending') {self.onResolvedCallbacks.push(() => {setTimeout(()=>{try {let x = onFulfilled(self.value);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)});self.onRejectedCallbacks.push(() => {setTimeout(()=>{try {let x = onRejected(self.reason);resolvePromise(promise2,x,resolve,reject);} catch (e) {reject(e);}},0)});}});return promise2 } // 語法糖 (甜) 目的是解決promise嵌套問題的 Q.derfer() Promise.defer = Promise.deferred = function(){let dfd = {};dfd.promise = new Promise((resolve,reject)=>{dfd.resolve = resolve;dfd.reject = reject;})return dfd; } // 類上的方法 Promise.reject = function(reason){return new Promise((resolve,reject)=>{reject(reason);}) } Promise.resolve = function(value){return new Promise((resolve,reject)=>{resolve(value);}) } Promise.prototype.catch = function(onRejected){// 默認不寫成功return this.then(null,onRejected); }; // all方法 Promise.all = function(promises){return new Promise((resolve,reject)=>{let arr = [];let i = 0;function processData(index,data){arr[index] = data;if(++i == promises.length){resolve(arr);}}for(let i = 0;i<promises.length;i++){promises[i].then(data=>{ // data是成功的結果processData(i,data);},reject);}}) } // 以請求最快的為準 Promise.race = function(promises){return new Promise((resolve,reject)=>{for(let i = 0;i<promises.length;i++){promises[i].then(resolve,reject);}}) } module.exports = Promise; 復制代碼

    總結

    以上是生活随笔為你收集整理的promise是什么?简单分析promise原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。