1. 程式人生 > >嘗試去實現一個Promise

嘗試去實現一個Promise


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 && arg instanceof Promise) {//引數是Promise物件的話直接返回 return arg; } else {//否則用引數構造一個Promise物件 var result = new Promise((arg && arg.then) || null,(arg && arg.then) ? null : arg,'fulfilled'); //result.resolve(arg); return result; } } Promise.reject = function(arg) {//同resolve if (arg && arg instanceof Promise) { return arg; } else { var result = new Promise((arg && arg.then) || null,(arg && arg.then) ? 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;

相關推薦

嘗試實現一個Promise

function resolve_promise_value(promise,value) {//PromiseA+的實現 var then; /* ret false 說明沒有執行promise._resolve裡的函式

mktime很慢就自己實現一個

tdi ati 十分 ace += timestamp src clas [] mktime很慢就自己去實現一個吧

老生常談-實現一個Promise

前言 在寫這個promise之前,希望你已經對es6中的Promise很熟悉了,概念性和基礎的東西就不再講了,不懂的同學可以去看看阮一峰老師的es6教程. 我主要按以下5個步驟來一步一步實現,非同步的實現我放在了後面,所以前面幾步暫不考慮 實現一個基本的MyPromise 實現then的鏈式呼叫

前端雜談: 如何實現一個 Promise?

前端雜談: 如何實現一個 Promise? 首先, 什麼是 Promise? A promise is an object that may produce a single value some time in the future: either a resolved value, or a reaso

實現一個Promise(基於Promise/A+規範)

前言 相信大家經常使用Promise,或者使用Generator、asnyc/await等非同步解決方案,網上的Promise原理也遍地開花。 一直以來想抽出時間也寫一寫Promise實現,但是平常工作也是忙的不可開交,正好元旦放了3天假期,休息了2天半,抽出半天時間來看一看Promise。 如何使用Pr

Promise進階——如何實現一個Promise

概述 從上次更新Promise/A+規範後,已經很久沒有更新部落格了。之前由於業務需要,完成了一個TypeScript語言的Promise庫。這次我們來和大家一步一步介紹下,我們如何實現一個符合Promise/A+規範的Promise庫。 如果對Promise/A+規範還不太瞭解的同學,建議先看看上一篇部

解析 Promise 原理,實現一個Promise

概述 這篇文章旨在解析 Promise的非同步實現原理,並且以 ES6中的 Promise 為藍本實現一個簡單的 Promise。 通過自己動手實現一個 Promise 物件,可以熟悉很多可能不知道的 Promise 細節,同時也能對非同步的理解更提升一步。

iOS:練習題中如何用技術實現一個連線題

// // LianXianComponentsView.m // LianxianDemo // // Created by 夏遠全 on 2018/2/6. // Copyright © 2018年 beijing. All rights reserved. // #import "LianX

實現一個Promise-polyfill

Promise Promise是ES6標準提供的一個非同步操作的很好的語法糖,對於原本的回撥函式模式進行了封裝,實現了對於非同步操作的鏈式呼叫。並且配上generator以及async語法糖來使用更加方便。 雖然Promise當前在很多瀏覽器上都已經得到了支

手寫實現一個promise

function myPromise (callback) { let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.fullF

手動實現一個Promise

ES6中實現的Promise是 Promise/A+ 規範。 首先,有三種狀態:pending ,fulfilled, rejected。 const PENDING = 'PENDING' const FULFILLED = 'FULFILLE

如何用原生JS實現一個簡單的promise

   我又又又回來了,最近真是累的跟狗一樣,急需一個大保健回覆一下子精力    我現在是一邊喝著紅牛一邊寫著部落格,好了好了,不扯了,迴歸整體好吧    先簡單來說一下啥是promise吧    它是什麼?Promise是一個方案,用來解決多層回撥巢狀的解決方案。它現在是ES6的原生物件。    &n

【JavaScript進階】深入理解JavaScript中ES6的Promise的作用並實現一個自己的Promise

  1.Promise的基本使用 1 // 需求分析: 封裝一個方法用於讀取檔案路徑,返回檔案內容 2 3 const fs = require('fs'); 4 const path = require('path'); 5 6 7 /** 8 * 把一個回

實現一個類,把冒泡和插入封裝到兩個函式中(宣告兩個函式,一個是冒泡,一個是插入),且進行呼叫和除錯

實現一個類,把冒泡和插入封裝到兩個函式中去(宣告兩個函式,一個是冒泡,一個是插入),且進行呼叫和除錯 import java.util.Arrays; /* * 實現一個類,把冒泡和插入封裝到兩個函式中去(宣告兩個函式,一個是冒泡,一個是插入),且進行呼叫和除錯 */ public class E

嘗試實現一個管理系統, 名字和電話號分別用兩個列表儲存 =======通訊錄管理系統======= 1.增加姓名和手機 2.刪除姓名 3.修改手機 4.查詢所有使用者 5.根據姓名查詢手機號 6.退出

name = [] tel = [] while True: print('==通訊錄管理系統==') print('1.增加姓名和手機') print('2.刪除姓名') print('3.修改手機') print

ES6——手把手實現一個簡單的Promise

想要實現一個Promise,首先當然得先知道這個東西是什麼,Promise物件是ES6給我們提供的一個解決非同步回撥的一個語法糖,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。把非同步操作放入Promise物件中,等到Promise物件中

實現一個自己的promise

這是小弟的一篇開篇小作,如有不當之處,請各位道友批評指正。本文將探討Promise的實現。 一、ES6中的Promise 1、簡介 據說js很早就實現了Promise,我是不知道的,我第

實現一個簡單的Promise

我們可以在chrome開發工具下看下原生 promise 是什麼: new Promise((resolve, reject) => {}) return Promise { [[Pro

給Array實現一個方法,重後返回重複的字元

程式碼如下: let arr = [1, 6, 8, 3, 7, 9, 2, 7, 2, 4, 4, 3, 3, 1, 5, 3] Array.prototype.removeDuplication

Promise 實現一個訊息佇列

需求描述 在此篇部落格中,我們的需求如下: 有一個訊息排程器去操作傳送來訊息 但處理訊息花費的事件是不確定的,有多有少 訊息是不斷髮送過來的 這個時候就會出現一種情況:前一條訊息還未執行結束,後一條訊息就被髮送過來了 如果這個時候要求後一條訊息必須在前一條執行完