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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

来,一起来实现一个符合Promise/A+的Promose(1.0.1版本)

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 来,一起来实现一个符合Promise/A+的Promose(1.0.1版本) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Promose是什么?(必要的科普)

為解決異步函數的回調陷阱,開發社區不斷摸索,終于折騰出 Promise/A+。它的優勢非常顯著:

  • 不增加新的語法,可以立刻適配幾乎所有瀏覽器
  • 以隊列的形式組織代碼,易讀好改
  • 捕獲異常方案也基本可用
  • 這套方案在迭代中逐步完善,最終被吸收進 ES2015。不僅如此,ES2017 中還增加了 Await/Async,可以用順序的方式書寫異步代碼,甚至可以正常拋出捕獲錯誤,維護同一個棧。可以說徹底解決了異步回調的問題。

    現在大部分瀏覽器和 Node.js 都已原生支持 Promise,很多類庫也開始返回 Promise 對象,更有各種降級適配策略。Node.js 7+ 則實裝了 Await/Async。


    Promose的基本用法

    let Mypromise = require('./Promise') // 這個是自己寫的 Promise 函數 底下有代碼講解 let p1 = new Mypromise(function(resolve,reject){resolve('666') }) p1.then(function(data){console.log(data) },function(err){console.log(err) })復制代碼

    Promise 是一個代理對象,它和原先的異步操作并無關系。它接受一個“執行器 executor”作為參數,我們把原先要執行的異步(并非一定要異步,以后會說明,這里你可以先不深究)操作放進去。

    執行器在 Promise 實例創建后立刻開始執行。執行器自帶兩個參數:resolve 和 reject,這二位都是函數,執行它們會改變 Promise 實例的狀態。

    Promise 實例有三個狀態:

  • pending [待定] 初始狀態,新創建的實例處于這個狀態
  • fulfilled [實現] 操作成功,在執行器里調用 resolve() 之后,實例切換到這個狀態
  • rejected [被否決] 操作失敗,在執行器里調用 reject() 之后,實例切換到這個狀態
  • Promise 實例狀態改變之后,就會觸發后面對應的 .then() 參數里的函數,繼續執行后續步驟。另外,Promise 的實例狀態只會改變一次,確定為 fulfilled 或 rejected 之一后就不會再變。


    我們來看看??Promise函數方面代碼要怎么實現:

    function Promise(executor) { // executor是一個執行函數let self = this; // 緩存this 防止出錯 self.status = 'pending'; // 初始化狀態self.value = undefined; // 默認成功的值self.reason = undefined; // 默認失敗的原因function resolve(value) { // 成功狀態if (self.status === 'pending') { // 判斷當前當前狀態self.status = 'resolved'; // 把pending 狀態變成 成功的狀態 resolvedself.value = value; // 給默認成功狀態 賦值}}function reject(reason) { // 失敗狀態if (self.status === 'pending') { // 判斷 Promise 當前狀態 如果是初始化 self.status = 'rejected'; // pending 狀態變成 失敗的狀態 rejectedself.reason = reason; // 給默認失敗的原因賦值}}try {executor(resolve, reject)} catch (e) { // 捕獲執行的時候發生異常,就直接失敗了 當 new 一個 新的 Promise對象 拋出一個錯誤時候// 如 在 Promise實例里 throw new Error('錯誤了')reject(e);} }Promise.prototype.then = function(onFulfilled, onReject){ let self = this; if(self.status === 'resolved'){ // onFulfilled(self.value)}if(self.status === 'rejected'){onReject(self.reason)} } module.exports = Promise;復制代碼

    以上是Promise最基本的實現


    我們來試試看運行結果: 當Primose 實例狀態為 resolve(成功)的時候,顯示結果如下




    接下來測試下:??當Primose 實例狀態為 reject(失敗)的時候 顯示如下


    從代碼結果來看,現在Promise 函數 內部的 ‘ pedding’ 狀態 已經可以 根據 成功和數百的狀態來改變了?

    當如果兩個函數同時運行呢!!!如下?


    只會顯示一個結果 誰先執行 狀態就變成誰 不會 同時 執行兩個結果??

    現在我們已經初步實現了 Promise 函數 的同步方法了?

    接下來繼續 實現其他的 如(多次then ,異步,Promise (then返回一個新的Promise對象))


    promise實例可以多次then,當成功后會將 then 中的成功方法按順序執行,我們可以先講then中成功的回調存到數組內,當成功是調用成功的數組即可,失敗的時候也同理

    定義兩個接收 成功的數組 和失敗的數組 如下:

    function Promise(executor) { // executor是一個執行函數let self = this;self.status = 'pending';self.value = undefined; // 默認成功的值self.reason = undefined; // 默認失敗的原因self.onResolvedCallbacks = []; // 存放then成功的回調self.onRejectedCallbacks = []; // 存放then失敗的回調function resolve(value) { // 成功狀態if (self.status === 'pending') {self.status = 'resolved';self.value = value;// 當成功以后, 依次執行成功數組里面的函數self.onResolvedCallbacks.forEach(function (fn) {fn();});}}function reject(reason) { // 失敗狀態if (self.status === 'pending') {self.status = 'rejected';self.reason = reason;// 當失敗以后, 依次執行失敗數組里面的函數self.onRejectedCallbacks.forEach(function (fn) {fn();})}}try {executor(resolve, reject)} catch (e) { // 捕獲的時候發生異常,就直接失敗了reject(e);} }復制代碼

    然后在 then方法中也需要判斷當前的狀態? ?如果是?pending則需要做下處理

    Promise.prototype.then = function(onFulfilled, onReject){let self = this;if(self.status === 'resolved'){ //onFulfilled(self.value)}if(self.status === 'rejected'){onReject(self.reason)}// 當調用then時可能沒成功 也沒失敗 if (self.status === 'pending') {// 此時沒有 resolve 也沒有 rejectself.onResolvedCallbacks.push(function(){onFulfilled(self.value)})self.onRejectedCallbacks.push(function(){onReject(self.reason)})} }復制代碼

    執行實例代碼: 結果如下


    用了兩次 then : 顯示都成功了? 調用多少次then 就顯示多少個成功


    鏈式調用 jquery,jquery能實現鏈式調用靠的就是返回this,promise不能返回this,promise實現鏈式調用靠的是返回一個新的promise,如果then中無論是成功的回調還是失敗的回調只要返回了結果就會走下一個then中的成功,如果有錯誤走下一個then的失敗

    實例代碼如下:

    let p = new Promise(function(resolve,reject){resolve(); }) let p2 = p.then(function(){throw new Error('錯誤'); }) p2.then(function(){ // 可以返回一個新的 Promise },function(err){console.log(err); // 這邊輸出錯誤 })復制代碼

    代碼如下:

    Promise.prototype.then = function(onFulfilled, onReject){let self = this;let promise2; //返回的promiseif (self.status === 'resolved') {promise2 = new Promise(function (resolve, reject) {try{onFulfilled(self.value);}catch (e){reject(e)}})}if (self.status === 'rejected') {promise2 = new Promise(function (resolve, reject) {try{onReject(self.reason)}catch (e){reject(e)}})}// 當調用then時可能沒成功 也沒失敗if (self.status === 'pending') {promise2 = new Promise(function (resolve, reject) {// 此時沒有resolve 也沒有rejectself.onResolvedCallbacks.push(function () {try{onFulfilled(self.value)}catch (e){reject(e)}});self.onRejectedCallbacks.push(function () {try{onReject(self.reason)}catch (e){reject(e)}});})}return promise2; }復制代碼如果第一個promise返回一個普通值,會進到下一次then的成功的回調,如果第一個promise返回了一個promise,需要等待返回的promise執行后的結果傳遞給下一次then中
    let p1 = new Promise(function(resolve,reject){resolve('333') }) p1.then(function(data){return new Promise(function(resolve,reject){setTimeout(function () {resolve(100)},1000)}) },function(err){throw new Error('失敗') }).then(function (data) {console.log(data) },function (err) {console.log(err) })復制代碼


    Promise.prototype.then = function(onFulfilled, onReject){let self = this;let promise2; //返回的promiseif (self.status === 'resolved') {promise2 = new Promise(function (resolve, reject) {// 當成功或者失敗執行時有異常那么返回的promise應該處于失敗狀態// x可能是一個promise 也有可能是一個普通的值try{let x = onFulfilled(self.value);// x可能是別人promise,寫一個方法統一處理resolvePromise(promise2, x, resolve, reject);}catch (e){reject(e)}})}if (self.status === 'rejected') {promise2 = new Promise(function (resolve, reject) {try{let x = onRjected(self.reason);resolvePromise(promise2, x, resolve, reject);}catch (e){reject(e)}})}// 當調用then時可能沒成功 也沒失敗if (self.status === 'pending') {promise2 = new Promise(function (resolve, reject) {// 此時沒有resolve 也沒有rejectself.onResolvedCallbacks.push(function () {try{let x = onFulfilled(self.value);resolvePromise(promise2, x, resolve, reject);}catch (e){reject(e)}});self.onRejectedCallbacks.push(function () {try{let x = onRjected(self.reason);resolvePromise(promise2, x, resolve, reject);}catch (e){reject(e)}});})}return promise2; }復制代碼

    接下來實現?resolvePromise 函數

    function resolvePromise(promise2, x, resolve, reject) {// 有可能這里返回的x是別人的promise// 盡可能允許其他亂寫if (promise2 === x) { //這里應該報一個類型錯誤,有問題return reject(new TypeError('循環引用了'))}// 看x是不是一個promise,promise應該是一個對象let called; // 表示是否調用過成功或者失敗if (x !== null && (typeof x === 'object' || typeof x === 'function')) {// 可能是promise {},看這個對象中是否有then方法,如果有then我就認為他是promise了try { // {then:1}let then = x.then;if (typeof then === 'function') {// 成功then.call(x, function (y) {if (called) returncalled = true// y可能還是一個promise,在去解析直到返回的是一個普通值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); // 表示成功了} }復制代碼快速實現常用的其他 Promise 方法:// 捕獲錯誤的方法 Promise.prototype.catch = function (callback) {return this.then(null, callback) } // 解析全部方法 Promise.all = function (promises) {//promises是一個promise的數組return new Promise(function (resolve, reject) {let arr = []; //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)}}) } // 只要有一個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);}) } Promise.defer = Promise.deferred = function () {let dfd = {};dfd.promise = new Promise(function (resolve, reject) {dfd.resolve = resolve;dfd.reject = reject;});return dfd }復制代碼

    寫在結尾: 第一次寫文章,邏輯有點亂,希望能幫上大家,大家不要噴,有什么錯誤,請指出,很感謝!肯定會重寫寫一遍,更好的給大家


    總結

    以上是生活随笔為你收集整理的来,一起来实现一个符合Promise/A+的Promose(1.0.1版本)的全部內容,希望文章能夠幫你解決所遇到的問題。

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