摘要:的實現說明沒有執行里的函數說明執行了里的函數說明執行里的函數過程中出現錯誤和執行狀態時的回調函數后返回的結果都需要執行傳進來的對象不能等于當前的對象回調返回的值或者的值是對象時需要等待該對象的狀態變更設置當前狀態的狀態和值執行回調隊列里的函
function resolve_promise_value(promise,value) {//PromiseA+的實現 var then; /* ret false 說明沒有執行promise._resolve里的函數 ret true 說明執行了promise._resolve里的函數 ret error 說明執行promise._resolve里的函數過程中出現錯誤 */ var ret = false; /* resolve(promise)和執行resolve狀態時的回調函數后返回的結果都需要執行resolve(promise,value) */ if (value === promise) {//傳進來的對象不能等于當前的Promise對象 promise.reject(new TypeError("TypeError")); } else if (value && value instanceof Promise){//回調返回的值或者resolve的值是Promise對象時需要等待該Promise對象的狀態變更 value.then(promise.resolve.bind(promise),promise.reject.bind(promise)); } else if (type(value) === "Object" || type(value) === "Function") { try { then = value.then; } catch(getThenErr) { promise.reject(thenErr); } if (type(then) === "Function") { try { then.call(value,promise.resolve.bind(promise),promise.reject.bind(promise)); } catch(callThenErr) { if (promise.state === "pending") { promise.reject(callThenErr); } } } else { ret = true; var fn; promise.setState("fulfilled");//設置當前Promise狀態的狀態和值 promise.value = value; var error; while (fn = promise._resolve.shift()) {//執行resolve回調隊列里的函數 try { if (typeof fn == "function") { var result = fn(value); promise.value = result; } } catch (err) { ret || (ret = err);//記錄第一個執行出錯的函數的異常信息 } } } } else { ret = true; var fn; promise.setState("fulfilled");//設置當前Promise狀態的狀態和值 promise.value = value; var error; while (fn = promise._resolve.shift()) {//執行resolve回調隊列里的函數 try { if (typeof fn == "function") { var result = fn(value); promise.value = result; } } catch (err) { (ret instanceof Error) || (ret = err); } } } if (promise.next) { if (ret === true) { resolve_promise_value(promise.next,promise.value); } else if (ret instanceof Error){ promise.next.reject(ret); } } } function type(arg) {//判斷對象類型函數 return Object.prototype.toString.call(arg).match(/ (w+)/)[1]; } function Promise(fn,value,state) { if (!(this instanceof Promise)) {//防止不用new調用Promise函數 return new Promise(fn); } this._resolve = [];//Promise對象的fulfilled時執行的回調隊列 this._reject = [];//Promise對象的rejected時執行的回調隊列 this.next = null;//執行下一個Promise對象 this.value = value || null;//當前Promise對象的值 this.state = state || "pending";//當前Promise對象的狀態 this.id = Promise.idFactory(); /* new 的時候如果有函數,就執行該函數,把resolve和reject函數作為參數傳進去,并且綁定對應的Promise對象 */ try { fn && fn(this.resolve.bind(this),this.reject.bind(this)); } catch (e) { this.reject(e); } } Promise.prototype = { equal: function(promise) {//根據id判斷兩個Promise對象是否相等 return promise && (type(promise.then) === "Function") && (this.id === promise.id); }, resolve: function(value) { if(this.state !== "pending"){ return; } setTimeout((function() { resolve_promise_value(this,value) }).bind(this),0); }, setState: function(state) {//設置Promise對象的狀態 this.state = state; }, reject: function(value) { if (this.state === "pending") { setTimeout((function() { this.setState("rejected");//設置Promise對象狀態 this.value = value;//記錄Promise對象對應的值 var fn; var error; if (this._reject.length === 0) { if (this.next) { this.next.reject(value); } return; } while (fn = this._reject.shift()) {//執行reject回調函數 try { if (typeof fn == "function") {//對于回調函數隊列,只需記錄最后一個函數的執行結果 var result = fn(value); this.value = result; } } catch (err) {//捕獲異常,保證回調隊列里的函數每一個都被執行 error || (error = err); } } if (this.next) { if (error) { this.next.reject(error); } /* 執行完當前Promise對象的回調后,如果Promise鏈上有下一個Promise對象,繼續執行,當前的Promise對象的值傳進去 如果error為true則說明上面代碼執行中有異常,把異常對象傳給下一個Promise對象 */ else { resolve_promise_value(this.next,result); } } }).bind(this),0) } }, then: function(resolve,reject) {//增加resolve和reject回調 if (this.state != "pending") {//如果當前Promise對象已經resolve或reject則根據當前Promise對象狀態異步執行傳進來的resolve或reject函數 this.state === "fulfilled" ? (resolve = resolve || function() {}) : (reject = reject || function() {}); setTimeout(this.state === "fulfilled" ? resolve.bind(null,this.value) : reject.bind(null,this.value),0); return; } (type(resolve) === "Function") && this._resolve.push(resolve);//記錄resolve回調 (type(reject) === "Function") && this._reject.push(reject); this.next = new Promise();//返回一個新的Promise對象 return this.next; }, catch: function(reject) {//then(undefined,callback)的語法糖 return this.then(void 0,reject); } } Promise.all = function(promiseArr) { if (type(promiseArr) !== "Array") {//參數需要Promise數組 new Error("need a Array"); } var count = 0; var result = [];//記錄每個Promise的結果 var ret = new Promise();//返回新的Promose對象 for (var i = 0; i< promiseArr.length ;i++) { promiseArr[i].then((function(i) {//每個Promise fulfilled后記錄結果并且判斷是否全部Promise對象已經fulfilled return function(value) { result[i] = value; count++; if (count === promiseArr.length) {//全部Promise fulfilled的話就執行resovle ret.resolve(result); } } })(i),function(value) { if (ret.state === "pending") {//有一個Promise對象reject并且ret還是pending狀態的話就直接返回 ret.reject(value); } }) } return ret; } Promise.race = function(promiseArr) { if (type(promiseArr) !== "Array") { new Error("need a Array"); } var ret = new Promise(); for (var i = 0; i< promiseArr.length ;i++) { promiseArr[i].then(function(value) { if (ret.state === "pending") {//有一個Promise對象resolve的話就返回,并且放棄其余的Promise對象的結果 ret.resolve(value); } },function(value) { if (ret.state === "pending") {//有一個Promise對象reject的話就返回,并且放棄其余的Promise對象的結果 ret.reject(value); } }); } return ret; } Promise.resolve = function(arg) { if (arg && typeof arg.then === "function") {//參數是Promise對象的話直接返回 return arg; } else {//否則用參數構造一個Promise對象 var result = new Promise(null,arg,"fulfilled"); //result.resolve(arg); return result; } } Promise.reject = function(arg) {//同resolve if (arg && typeof arg.then === "function") { return arg; } else { var result = new Promise(null,arg,"reject"); //result.reject(arg); return result; } } Promise.idFactory = (function() {//id構造工廠,id用于比較是否是同一個Promise對象 var _id = 0; return function() { return _id += 1; } })(); module.exports = Promise;
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81568.html
摘要:結果打印我結論或問題這里我們基礎實現了一個可以用于生產環境的后續我們會接續完善這個的特有方法,比如等后續再介紹用實現的自動執行器等附錄參考中文對象入門阮一峰 PHP下的異步嘗試系列 如果你還不太了解PHP下的生成器和協程,你可以根據下面目錄翻閱 PHP下的異步嘗試一:初識生成器 PHP下的異步嘗試二:初識協程 PHP下的異步嘗試三:協程的PHP版thunkify自動執行器 PHP下的...
摘要:取而代之,利用事件循環體系,使用了一種類似語法的工作方式一旦非阻塞的異步操作完成之后,就可以讓開發者分配的回調函數被觸發。第一個嘗試嵌套的回調函數下面是使用嵌套的回調函數的實現方法這可能對于任何使用者來說再熟悉不過了。 寫在文章前 這篇文章翻譯自 ASYNC/AWAIT WILL MAKE YOUR CODE SIMPLER,這是一篇寫于2017年八月的文章,并由某專欄提名為17年十大...
摘要:說到異步操作,可能想到的是這樣以的為例對于的操作來說,是一個異步的過程,通過回調函數,在得到返回的時候才會去執行操作。 showImg(https://segmentfault.com/img/bVtSd1); 瀏覽器支持 showImg(https://segmentfault.com/img/bVtSd8);http://caniuse.com/promises/embed/age...
摘要:本篇文章將會嘗試用簡單易懂的語言描述的原理,并且用手擼一個簡單的。一個后可以通過方法,指定和時的回調函數。實現實現狀態機因為是一個構造函數,使用的寫法,首先想到的就是有顯式聲明的。 說到Promise,都知道它是比回調函數更優的一種異步編程解決方案,它可以使得異步操作邏輯變得更加清晰,是解決地獄回調的一種嘗試。本篇文章將會嘗試用簡單易懂的語言描述Promise的原理,并且用es6手擼一...
摘要:單線程就意味著,所有任務需要排隊,前一個任務結束,才會執行后一個任務。這決定了它只能是單線程,否則會帶來很復雜的同步問題。小結本身是單線程的,并沒有異步的特性。當異步函數執行時,回調函數會被壓入這個隊列。 走在前端的大道上 本篇將自己讀過的相關 js異步 的文章中,對自己有啟發的章節片段總結在這(會對原文進行刪改),會不斷豐富提煉總結更新。 概念 JS 是單線程的語言。 單線程就意味著...
閱讀 1640·2023-04-25 20:36
閱讀 2049·2021-09-02 15:11
閱讀 1177·2021-08-27 13:13
閱讀 2653·2019-08-30 15:52
閱讀 4589·2019-08-29 17:13
閱讀 1001·2019-08-29 11:09
閱讀 1491·2019-08-26 11:51
閱讀 833·2019-08-26 10:56