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