min-promise
Advanced tools
Comparing version 1.0.3 to 2.0.0
@@ -1,22 +0,9 @@ | ||
var Promise = require('./') | ||
var resolved = require('./resolved') | ||
var rejected = require('./rejected') | ||
var deferred = require('./deferred') | ||
module.exports = { | ||
resolved: function(value) { | ||
return new Promise(function(resolve, reject) { | ||
resolve(value) | ||
}) | ||
}, | ||
rejected: function(reason) { | ||
return new Promise(function(resolve, reject) { | ||
reject(reason) | ||
}) | ||
}, | ||
deferred: function() { | ||
var ret = {} | ||
ret.promise = new Promise(function(resolve, reject) { | ||
ret.resolve = resolve | ||
ret.reject = reject | ||
}) | ||
return ret | ||
} | ||
var adapter = module.exports = { | ||
resolved: resolved, | ||
rejected: rejected, | ||
deferred: deferred | ||
} |
129
index.js
@@ -22,5 +22,6 @@ // Promises/A+: https://promisesaplus.com/ | ||
module.exports = BasePromise | ||
// module.exports = BasePromise | ||
module.exports = Promise | ||
// ecma constructor | ||
// constructor | ||
function Promise(executor) { | ||
@@ -44,2 +45,3 @@ var me = this | ||
this.state = pending | ||
// this.id = Math.random() // for debug | ||
} | ||
@@ -50,2 +52,3 @@ | ||
proto.then = function(onFulfilled, onRejected) { | ||
var me = this | ||
var ret = new BasePromise | ||
@@ -55,3 +58,7 @@ var handlers = ret.handlers | ||
handlers[rejected] = onRejected | ||
this.children.push(ret) | ||
if (pending == me.state) { | ||
me.children.push(ret) | ||
} else { | ||
triggerHandler(ret, me.state, me.result) | ||
} | ||
return ret | ||
@@ -61,8 +68,42 @@ } | ||
var setResult = _.curry(function(promise, state, result) { | ||
if (isThenable(result)) { | ||
result.then(function(value) { | ||
setResult(promise, fulfilled, value) | ||
}, function(reason) { | ||
setResult(promise, rejected, reason) | ||
if (promise === result) { | ||
// 2.3.1 | ||
return setResult(promise, rejected, new TypeError('circle promise')) | ||
} | ||
// important, only pending can be set result | ||
if (promise.state != pending) return | ||
if (promise.called) return | ||
var then | ||
// important, get then can crash | ||
try { | ||
// 2.3.3.1 | ||
then = getThenFn(result) | ||
} catch (e) { | ||
// 2.3.3.2 | ||
return setResult(promise, rejected, e) | ||
} | ||
if (then) { | ||
// important, should has context should be result | ||
// thenFn can also be crashed | ||
var onceSet = _.once(function(state, result) { | ||
// 2.3.3.3.3 | ||
if (state == rejected) { | ||
finalSetResult(promise, state, result) | ||
} else { | ||
setResult(promise, state, result) | ||
} | ||
}) | ||
try { | ||
// 2.3.3.3 | ||
then.call(result, function(value) { | ||
// 2.3.3.3.1 | ||
onceSet(fulfilled, value) | ||
}, function(reason) { | ||
// 2.3.3.3.2 | ||
onceSet(rejected, reason) | ||
}) | ||
} catch (e) { | ||
// 2.3.3.3.4 | ||
onceSet(rejected, e) | ||
} | ||
} else { | ||
@@ -73,8 +114,7 @@ finalSetResult(promise, state, result) | ||
function finalSetResult(promise, state, result) { | ||
// result 不是 thenable | ||
promise.state = state | ||
promise.result = result | ||
_.each(promise.children, function(child) { | ||
var handler = child.handlers[state] | ||
function triggerHandler(promise, state, result) { | ||
if (state == null) debugger | ||
// should always async, important | ||
_.delay(function() { | ||
var handler = promise.handlers[state] | ||
if (is.fn(handler)) { | ||
@@ -85,5 +125,9 @@ var value | ||
} catch (reason) { | ||
return setResult(child, rejected, reason) | ||
// use final because reason should never be promise | ||
return finalSetResult(promise, rejected, reason) | ||
} | ||
setResult(child, fulfilled, value) | ||
setResult(promise, fulfilled, value) | ||
} else { | ||
// chain to child | ||
setResult(promise, state, result) | ||
} | ||
@@ -93,46 +137,21 @@ }) | ||
function isThenable(val) { | ||
return is.fn(_.get(val, 'then')) | ||
} | ||
// other shit | ||
proto['catch'] = function(onRejected) { | ||
// es3 like IE8- not support because catch is keyword | ||
return this.then(undefined, onRejected) | ||
} | ||
Promise.resolve = function(val) { | ||
return new Promise(function(resolve) { | ||
resolve(val) | ||
function finalSetResult(promise, state, result) { | ||
// set result, ignore if result is thenable | ||
promise.state = state | ||
promise.result = result | ||
_.each(promise.children, function(child) { | ||
triggerHandler(child, state, result) | ||
}) | ||
} | ||
Promise.reject = function(reason) { | ||
return new Promise(function(resolve, reject) { | ||
reject(reason) | ||
}) | ||
} | ||
Promise.all = function() { | ||
} | ||
Promise.race = function() { | ||
} | ||
/* | ||
var p = new Promise | ||
p.then(function(x) { | ||
return x + 1 | ||
}).then(function(x) { | ||
return { | ||
then: function(resolve) { | ||
setTimeout(resolve, 1000, x + 3) | ||
function getThenFn(obj) { | ||
// 2.3.3 Otherwise, if x is an object or function | ||
if (is.oof(obj)) { | ||
// may be getter | ||
var fn = obj.then | ||
if (is.fn(fn)) { | ||
return fn | ||
} | ||
} | ||
}).then(function(x) { | ||
console.log(x) | ||
}) | ||
} | ||
setResult(p, fulfilled, 3) | ||
*/ |
{ | ||
"name": "min-promise", | ||
"version": "1.0.3", | ||
"version": "2.0.0", | ||
"description": "Small Promise that realize the Promise standard", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha test" | ||
"test": "node promise-a-test.js", | ||
"readme": "pretty-readme > readme.md" | ||
}, | ||
@@ -15,4 +16,4 @@ "author": "chunpu", | ||
"devDependencies": { | ||
"promises-aplus-tests": "^2.1.1" | ||
"promises-aplus-tests": "latest" | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
15
2597
1
36
0
69878