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