function Promise(executor) {
let self = this;
if (typeof executor !== 'function') throw new TypeError('Promise resolver ' + executor + ' is not a function');
if (!(self instanceof Promise)) throw new TypeError('undefined is not a promise');
self.state = 'pending';
self.value = undefined;
self.onfulfilledCallbacks = [];
self.onRejectedCallbacks = [];
const change = function change(state, value) {
if (self.state !== 'pending') return;
self.state = state;
self.value = value;
const callbacks = self.state === "fulfilled" ? self.onfulfilledCallbacks : self.onRejectedCallbacks;
for (let i = 0; i < callbacks.length; i++) {
let callback = callbacks[i];
if (typeof callback === 'function') callback(self.value);
}
};
try {
executor(function resolve(value) {
change('fulfilled', value);
}, function reject(reason) {
change('rejected', reason);
});
} catch (err) {
change('rejected', err.message);
}
}
const resolvePromise = function resolvePromise(promise, x, resolve, reject) {
if (x === promise) throw new TypeError('Chaining cycle detected for promise #<Promise>');
if (x !== null && /^(object|function)$/i.test(typeof x)) {
let then;
try {
then = x.then;
} catch (err) {
reject(err);
}
if (typeof then === 'function') {
let called = false;
try {
then.call(x, function onfulfilled(x) {
if (called) return;
called = true;
resolvePromise(promise, x, resolve, reject);
}, function onRejected(r) {
if (called) return;
called = true;
reject(r);
});
} catch (err) {
if (called) return;
reject(err);
}
return;
}
}
resolve(x);
};
const handle = function handle(callback, value, promise, resolve, reject) {
try {
let x = callback(value);
resolvePromise(promise, x, resolve, reject);
} catch (err) {
reject(err);
}
};
Promise.prototype = {
constructor: Promise,
then: function then(onfulfilled, onRejected) {
const self = this;
let promise = null;
if (typeof onfulfilled !== 'function') {
onfulfilled = function onfulfilled(value) {
return value;
};
}
if (typeof onRejected !== 'function') {
onRejected = function onRejected(reason) {
throw reason;
};
}
promise = new Promise(function (resolve, reject) {
switch (self.state) {
case 'fulfilled':
handle(onfulfilled, self.value, promise, resolve, reject);
break;
case 'rejected':
handle(onRejected, self.value, promise, resolve, reject);
break;
default:
self.onfulfilledCallbacks.push(function (value) {
handle(onfulfilled, value, promise, resolve, reject);
});
self.onRejectedCallbacks.push(function (reason) {
handle(onRejected, reason, promise, resolve, reject);
});
}
});
return promise;
},
catch: function my_catch(onRejected) {
return this.then(null, onRejected);
}
};
if (typeof Symbol !== "undefined") Promise.prototype[Symbol.toStringTag] = 'Promise';
Promise.resolve = function resolve(value) {
return new Promise(function (resolve) {
resolve(value);
});
};
Promise.reject = function reject(reason) {
return new Promise(function (_, reject) {
reject(reason);
});
};
const isPromise = function isPromise(x) {
if (x !== null && /^(object|function)$/i.test(typeof x)) {
if (typeof x.then === 'function') {
return true;
}
}
return false;
};
Promise.all = function all(promises) {
if (!Array.isArray(promises)) throw new TypeError('promises must be an Array');
let n = 0,
results = [];
return new Promise(function (resolve, reject) {
for (let i = 0; i < promises.length; i++) {
(function (i) {
let promise = promises[i];
if (!isPromise(promise)) promise = Promise.resolve(promise);
promise.then(function onfulfilled(value) {
n++;
results[i] = value;
if (n >= promises.length) resolve(results);
}).catch(function onRejected(reason) {
reject(reason);
});
})(i);
}
});
};
Promise.deferred = function deferred() {
const result = {};
result.promise = new Promise(function (resolve, reject) {
result.resolve = resolve;
result.reject = reject;
});
return result;
};
const _promise_ = new Promise((resolve, reject) => {
console.log(`sync..`)
resolve(101)
})
_promise_.then((data) => {
console.log(`sync..`);
console.log(data);
})
_promise_.then((data) => {
console.log(888);
console.log(data);
})
let p1 = new Promise(function (resolve, reject) {
resolve(`宝哥说给你10000000`);
});
p1.then(e => console.log(e));
let p2 = new Promise(function (resolve, reject) {
reject(`阿布反手拒绝你一个99999`);
});
p2.catch(err => console.log(`err`, err));
Promise.resolve("13122223333").then(v => console.log(v));