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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Promise 解析

發(fā)布時間:2025/7/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Promise 解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Promise

由于js的語言特性(用戶交互)和工作環(huán)境(瀏覽器腳本),決定了它是單線程工作,所以兩段腳本不能同時運行,但為了實現(xiàn)功能,所以人們使用了事件和回調(diào)來初步解決這個問題,例如(addEventListener),但這也帶來了嚴重的回調(diào)問題,非常容易陷入回調(diào)地獄的困惱,

由于這個問題。js發(fā)展至今,社區(qū)提出了promise(承若)標準,被es6寫入了語言標準中,統(tǒng)一了它的用法,并在原生中提供了標準的Promise對象

讓我們先來實例化一個標準的promise對象:

//實例化一個promise對象,這個對象有兩個參數(shù)(resolve-決定,reject-拒絕)let promise = new Promise((resolve,reject)=>{//延時3s,把promise的狀態(tài)改為resolve-決定setTimeout(function(){resolve('666')},3000)})//每個實例都有then()方法,用來獲取其值或原因。//then(onFulfilled, onRejected)//成功的回調(diào),失敗的回調(diào)promise.then(data=>{console.log(data)},err=>{console.error(err)}).then()

同時promise還可以多次調(diào)用then()方法,也可以在resolve中繼續(xù)拋出一個新的promise 例:

promise.then(function(data){console.log('data2=',data);},function(err){console.log('err2=',err);});

或者:

let promise2 = promise.then(function(data){return new Promise(function(resolve,reject){setTimeout(function(){resolve(data + '777' );},1000);});});

當然還有常見的all(),catch(),resolve(),reject()等等一些方法,而這些方法都是按照Promise/A+規(guī)范規(guī)定的 (詳情)

我們現(xiàn)在就按照這個規(guī)范來實現(xiàn)一個屬于我們自己的promise

首先我們先定義出這個類:

// executor是一個執(zhí)行函數(shù),在實例化的時候被傳入。這個函數(shù)會執(zhí)行兩個被傳入的狀態(tài)函數(shù) var Promise = function (executor) { let self = this;//沒個promise都會有個初始化值,這個值在規(guī)范中叫做pendingself.status = 'pending';self.value = undefined; // 默認成功的值self.reason = undefined; // 默認失敗的原因self.onResolvedCallbacks = []; // 存放then成功的回調(diào)self.onRejectedCallbacks = []; // 存放then失敗的回調(diào)// 成功狀態(tài)要執(zhí)行的函數(shù)function resolve(value) {//更改他的狀態(tài)值,為成功,且不能更改if (self.status === 'pending') {self.status = 'resolved';self.value = value;//實例多次調(diào)用then(),循環(huán)釋放數(shù)組self.onResolvedCallbacks.forEach(function (fn) {fn();});}}// 失敗狀態(tài)要執(zhí)行的函數(shù)function reject(reason) {//更改他的狀態(tài)值,為失敗,且不能更改if (self.status === 'pending') {self.status = 'rejected';self.reason = reason;//實例多次調(diào)用then(),循環(huán)釋放數(shù)組self.onRejectedCallbacks.forEach(function (fn) {fn();})}}如果直接傳入錯誤的代碼,那么直接進入rejecttry {executor(resolve, reject)} catch (e) {// 捕獲的時候發(fā)生異常,就直接失敗了reject(e);} }

下面我們來實現(xiàn)then()方法,個方法每個實例都有,他是一個方法,所以我們把它掛載到Promise原型上:

Promise.prototype.then = function (onFulfilled, onRjected) {//成功和失敗默認一個函數(shù),防止報錯,onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (value) {return value;}onRjected = typeof onRjected === 'function' ? onRjected : function (err) {throw err;}let self = this;//定義一個返回的promiselet promise2;//當狀態(tài)是成功的時候,可能會在函數(shù)中再次返回一個promiseif (self.status === 'resolved') {promise2 = new Promise(function (resolve, reject) {// 當成功或者失敗執(zhí)行時有異常那么返回的promise應(yīng)該處于失敗狀態(tài)//這個x 是第一個promise執(zhí)行后的結(jié)果// x可能是一個promise 也有可能是一個普通的值setTimeout(function () {try {let x = onFulfilled(self.value);// x可能是別人promise,寫一個方法統(tǒng)一處理resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}})})}//當狀態(tài)是失敗的時候if (self.status === 'rejected') {promise2 = new Promise(function (resolve, reject) {setTimeout(function () {try {let x = onRjected(self.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}})})}// 當調(diào)用then時可能沒成功 也沒失敗if (self.status === 'pending') {promise2 = new Promise(function (resolve, reject) {// 此時沒有resolve 也沒有rejectself.onResolvedCallbacks.push(function () {setTimeout(function () {try {let x = onFulfilled(self.value);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e)}})});self.onRejectedCallbacks.push(function () {setTimeout(function () {try {let x = onRjected(self.reason);resolvePromise(promise2, x, resolve, reject);} catch (e) {reject(e);}})});})}return promise2; }

集中處理x

function resolvePromise(promise2, x, resolve, reject) {// 有可能這里返回的x是別人的promise// 先跑錯if (promise2 === x) { //這里應(yīng)該報一個類型錯誤,有問題return reject(new TypeError('循環(huán)引用了'))}// 看x是不是一個promise,promise應(yīng)該是一個對象let called; // 表示是否調(diào)用過成功或者失敗if (x !== null && (typeof x === 'object' || typeof x === 'function')) {//根據(jù)語法規(guī)定的幾種情況來判斷// 可能是promise {},看這個對象中是否有then方法,如果有then我就認為他是promise了try {let then = x.then;if (typeof then === 'function') {// 成功then.call(x, function (y) {if (called) returncalled = true// y可能還是一個promise,在去解析直到返回的是一個普通值//遞歸調(diào)用這個函數(shù),resolvePromise(promise2, y, resolve, reject)}, function (err) { //失敗if (called) returncalled = truereject(err);})} else {resolve(x)}} catch (e) {if (called) returncalled = true;reject(e);}} else { // 說明是一個普通值1resolve(x); // 表示成功了} }

在實現(xiàn)了這些之后,其他的方法,更多的就是一個語法糖,我們來實現(xiàn)他們
catch:

catch實際上就是reject,所以一般建議在then里面不穿reject(),而鏈式調(diào)用catch方法Promise.prototype.catch = function (callback) {return this.then(null, callback)}

all

//會傳入一個數(shù)組,這個數(shù)組是promise集合 Promise.all = function (promises) {return new Promise(function (resolve, reject) {//arr是最終返回值的結(jié)果let arr = []; // 表示成功了多少次let i = 0; function processData(index, y) {arr[index] = y;if (++i === promises.length) {resolve(arr);}}for (let i = 0; i < promises.length; i++) {promises[i].then(function (y) {processData(i, y)}, reject)}}) }

race

//race就是賽跑的意思,誰獲取結(jié)果比較快,就返回誰 // 只要有一個promise成功了 就算成功。如果第一個失敗了就失敗了 Promise.race = function (promises) {return new Promise(function (resolve, reject) {for (var i = 0; i < promises.length; i++) {promises[i].then(resolve,reject)}}) } // 生成一個成功的promise Promise.resolve = function(value){return new Promise(function(resolve,reject){resolve(value);}) } // 生成一個失敗的promise Promise.reject = function(reason){return new Promise(function(resolve,reject){reject(reason);}) }

defer 延期處理
會包容promise 可用于封裝在傳遞方法之外調(diào)用原有的promise回調(diào)

Promise.defer = Promise.deferred = function () {let dfd = {};dfd.promise = new Promise(function (resolve, reject) {dfd.resolve = resolve;dfd.reject = reject;});return dfd }

轉(zhuǎn)載于:https://www.cnblogs.com/oicb/p/10568151.html

總結(jié)

以上是生活随笔為你收集整理的Promise 解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。