-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
454 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
22 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const fs = require('fs') | ||
let cc = {} | ||
|
||
let event = { | ||
arr:[], | ||
on(fn) { | ||
this.arr.push(fn) | ||
}, | ||
emit() { | ||
this.arr.forEach(fn => fn()) | ||
} | ||
} | ||
|
||
event.on(() => { | ||
console.log('订阅ok') | ||
}) | ||
|
||
event.on(() => { | ||
// console.log(Object.keys(cc)) | ||
// console.log(Object.keys(cc)) | ||
if(Object.keys(cc).length === 2) { | ||
console.log(cc) | ||
} | ||
}) | ||
|
||
fs.readFile('name.txt', (err, data) => { | ||
cc['name'] = data.toString() | ||
event.emit() | ||
}) | ||
fs.readFile('age.txt', (err, data) => { | ||
cc['age'] = data.toString() | ||
event.emit() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const fs = require('fs') | ||
let cc = {} | ||
|
||
const after = (times, fn) => () => --times === 0 && fn() | ||
let newA = after(2, ()=> { | ||
console.log(cc) | ||
}) | ||
|
||
fs.readFile('name.txt', (err, data) => { | ||
cc['name'] = data.toString() | ||
newA() | ||
}) | ||
fs.readFile('age.txt', (err, data) => { | ||
cc['age'] = data.toString() | ||
newA() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
class MyPromise { | ||
constructor(executor) { | ||
// 初始属性值 | ||
this.status = 'pending'; | ||
this.value = undefined; | ||
this.resolvedArr = []; | ||
this.rejectedArr = []; | ||
|
||
// 改变状态的函数 | ||
let changeStatus = (status, result) => { | ||
if (this.status !== 'pending') return; | ||
this.status = status; | ||
this.value = result; | ||
let arr = status === 'rejected' ? this.rejectedArr : this.resolvedArr; | ||
arr.forEach(item => (typeof item === 'function' ? item(this.value) : null)); | ||
}; | ||
let resolve = result => { | ||
if (this.resolvedArr.length > 0) { | ||
changeStatus('resolved', result); | ||
return; | ||
} | ||
let delayTimer = setTimeout(() => { | ||
clearTimeout(delayTimer); | ||
changeStatus('resolved', result); | ||
}, 0); | ||
}; | ||
let reject = reason => { | ||
if (this.rejectedArr.length > 0) { | ||
changeStatus('rejected', reason); | ||
return; | ||
} | ||
let delayTimer = setTimeout(() => { | ||
clearTimeout(delayTimer); | ||
changeStatus('rejected', reason); | ||
}, 0); | ||
}; | ||
|
||
// 异常捕获处理 | ||
try { | ||
executor(resolve, reject); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
} | ||
|
||
then(resolvedFn, rejectedFn) { | ||
if (typeof resolvedFn !== 'function') { | ||
resolvedFn = result => { | ||
return result; | ||
}; | ||
} | ||
if (typeof rejectedFn !== 'function') { | ||
rejectedFn = reason => { | ||
// throw new Error(reason); | ||
return new MyPromise((resolve, reject) => { | ||
reject(reason); | ||
}); | ||
}; | ||
} | ||
|
||
// then链:返回一个新的Promise实例 | ||
return new MyPromise((resolve, reject) => { | ||
this.resolvedArr.push(() => { | ||
try { | ||
let x = resolvedFn(this.value); | ||
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
this.rejectedArr.push(() => { | ||
try { | ||
let x = rejectedFn(this.value); | ||
x instanceof MyPromise ? x.then(resolve, reject) : resolve(x); | ||
} catch (error) { | ||
reject(error); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
catch (rejectedFn) { | ||
// catch(rejectedFn) === then(null,rejectedFn) | ||
return this.then(null, rejectedFn); | ||
} | ||
|
||
/* 静态方法 */ | ||
static resolve(result) { | ||
return new MyPromise(resolve => { | ||
resolve(result); | ||
}); | ||
} | ||
|
||
static reject(reason) { | ||
return new MyPromise((_, reject) => { | ||
reject(reason); | ||
}); | ||
} | ||
|
||
static all(arr) { | ||
return new MyPromise((resolve, reject) => { | ||
let index = 0, | ||
results = []; | ||
for (let i = 0; i < arr.length; i++) { | ||
let item = arr[i]; | ||
if (!(item instanceof MyPromise)) continue; | ||
item.then(result => { | ||
index++; | ||
results[i] = result; | ||
if (index === arr.length) { | ||
resolve(results); | ||
} | ||
}).catch(reason => { | ||
// 只要有一个失败,整体就是失败 | ||
reject(reason); | ||
}); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
const PENDING = 'pending' | ||
const RESOLVED = 'resolved' | ||
const REJECTED = 'rejected' | ||
const resolvePromise = (promise2, x, resolve, reject) => { | ||
if (promise2 === x) { | ||
// console.log('==') | ||
return reject(new TypeError('不能返回自己')) | ||
} | ||
|
||
if(x && typeof x === 'object' || typeof x === 'function') { | ||
let called // 默认没有调用成功 | ||
try { | ||
let then = x.then // 取then的时候可能会发生错误 例如getter | ||
if(typeof then === 'function') { | ||
then.call(x, y => { | ||
// resolve(y) | ||
// 递归解析promise | ||
if(called) return // 防止多次调用 | ||
called = true | ||
resolvePromise(promise2, y, resolve, reject) | ||
},r => { | ||
if(called) return | ||
called = true | ||
reject(r) | ||
}) | ||
} | ||
} catch (error) { | ||
if(called) return | ||
called = true | ||
reject(error) | ||
} | ||
} else { | ||
resolve(x) | ||
} | ||
} | ||
class Promise { | ||
constructor(excutor) { // excutor 立即执行的 | ||
this.state = PENDING | ||
this.value = undefined | ||
this.reason = undefined | ||
this.onResolvedCallbacks = [] | ||
this.onRejectedCallbacks = [] | ||
const resolve = (value) => { //成功 | ||
if(value instanceof Promise) { | ||
return value.then(resolve, reject) | ||
} | ||
if (this.state === PENDING) { | ||
this.state = RESOLVED | ||
this.value = value | ||
this.onResolvedCallbacks.forEach(fn => fn()) | ||
} | ||
} | ||
const reject = (reason) => { | ||
this.state = REJECTED | ||
this.reason = reason | ||
this.onRejectedCallbacks.forEach(fn => fn()) | ||
} | ||
try { | ||
excutor(resolve, reject) // 出错直接到reject | ||
} catch (error) { | ||
reject(error) | ||
} | ||
} | ||
|
||
then(onResolved, onRejected) { | ||
// 可选参数 穿透 | ||
onResolved = typeof onResolved === 'function' ? onResolved : value => value | ||
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err} | ||
// then 方法应该返回一个新的promise | ||
let promise2 = new Promise((resolve, reject) => { | ||
if (this.state === RESOLVED) { | ||
// console.log('resolved') | ||
setTimeout(() => { | ||
try { | ||
let res = onResolved(this.value) | ||
// console.log(res) | ||
resolvePromise(promise2, res, resolve, reject) | ||
} catch (error) { | ||
reject(error) | ||
} | ||
}) | ||
} | ||
if (this.state === REJECTED) { | ||
// console.log('rejected') | ||
setTimeout(() => { | ||
try { | ||
let res = onRejected(this.reason) | ||
resolvePromise(promise2, res, resolve, reject) | ||
} catch (error) { | ||
reject(error) | ||
} | ||
}) | ||
} | ||
if (this.state === PENDING) { | ||
// console.log('pending') | ||
this.onResolvedCallbacks.push(() => { | ||
// onResolved(this.value) | ||
setTimeout(() => { | ||
try { | ||
let res = onResolved(this.value) | ||
// console.log(res) | ||
resolvePromise(promise2, res, resolve, reject) | ||
} catch (error) { | ||
reject(error) | ||
} | ||
}) | ||
}) | ||
this.onRejectedCallbacks.push(() => { | ||
// onRejected(this.reason) | ||
setTimeout(() => { | ||
try { | ||
let res = onRejected(this.reason) | ||
resolvePromise(promise2, res, resolve, reject) | ||
} catch (error) { | ||
reject(error) | ||
} | ||
}) | ||
}) | ||
} | ||
}) | ||
return promise2 | ||
} | ||
catch(onRejected) { | ||
return this.then(null, onRejected) | ||
} | ||
static resolve(value) { | ||
return new Promise(resolve => { | ||
resolve(value) | ||
}) | ||
} | ||
static reject(reason) { | ||
return new Promise((resolve, reject) => { | ||
reject(reason) | ||
}) | ||
} | ||
static all(promises) { | ||
return new Promise((resolve, reject) => { | ||
let index = 0, results = [] | ||
for(let i = 0; i< promises.length; i++) { | ||
let item = promises[i] | ||
if(item instanceof Promise) { | ||
item.then(res => { | ||
results[i] = res | ||
index ++ | ||
if(index === promises.length) { | ||
resolve(results) | ||
} | ||
}).catch(reason => { | ||
reject(reason) | ||
}) | ||
} else { | ||
results[i] = item | ||
index ++ | ||
if(index === promises.length) { | ||
resolve(results) | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
static race(promises) { | ||
return new Promise((resolve, reject) => { | ||
promises.forEach(item => { | ||
if(item instanceof Promise) { | ||
item.then(res => resolve(res)) | ||
} else { | ||
resolve(item) | ||
} | ||
}) | ||
}) | ||
} | ||
} | ||
|
||
module.exports = Promise | ||
|
||
/* | ||
const handle = (cb, data) => { | ||
try { | ||
const res = cb(data) | ||
res instanceof Promise ? res.then(resolve, reject) : resolve(res) | ||
} catch (error) { | ||
reject(error) | ||
} | ||
} | ||
if(this.state === RESOLVED) { | ||
handle(onResolved, this.value) | ||
} | ||
if(this.state === REJECTED) { | ||
handle(onRejected, this.reason) | ||
} | ||
if(this.state === PENDING){ | ||
this.onResolvedCallbacks.push(() => { | ||
// onResolved(this.value) | ||
handle(onResolved, this.value) | ||
}) | ||
this.onRejectedCallbacks.push(() => { | ||
// onRejected(this.reason) | ||
handle(onRejected, this.reason) | ||
}) | ||
} | ||
*/ |
Oops, something went wrong.