From 209d154a1da920f2141afb62737799a7ca9f0936 Mon Sep 17 00:00:00 2001 From: YangJ0605 <1442122744@qq.com> Date: Sat, 6 Jun 2020 19:11:03 +0800 Subject: [PATCH] =?UTF-8?q?promise=20=E5=AE=9E=E7=8E=B02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0606/age.txt | 1 + 0606/event.js | 33 ++++++ 0606/fs.js | 16 +++ 0606/name.txt | 1 + 0606/pormise2.js | 120 +++++++++++++++++++ 0606/promise.js | 201 ++++++++++++++++++++++++++++++++ 0606/test.js | 24 ++++ better-scroll/1.js | 17 +++ better-scroll/1.txt | 1 + better-scroll/package-lock.json | 23 ++++ better-scroll/package.json | 17 +++ 11 files changed, 454 insertions(+) create mode 100644 0606/age.txt create mode 100644 0606/event.js create mode 100644 0606/fs.js create mode 100644 0606/name.txt create mode 100644 0606/pormise2.js create mode 100644 0606/promise.js create mode 100644 0606/test.js create mode 100644 better-scroll/1.js create mode 100644 better-scroll/1.txt create mode 100644 better-scroll/package-lock.json create mode 100644 better-scroll/package.json diff --git a/0606/age.txt b/0606/age.txt new file mode 100644 index 0000000..8fdd954 --- /dev/null +++ b/0606/age.txt @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/0606/event.js b/0606/event.js new file mode 100644 index 0000000..f236d6b --- /dev/null +++ b/0606/event.js @@ -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() +}) \ No newline at end of file diff --git a/0606/fs.js b/0606/fs.js new file mode 100644 index 0000000..423c099 --- /dev/null +++ b/0606/fs.js @@ -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() +}) \ No newline at end of file diff --git a/0606/name.txt b/0606/name.txt new file mode 100644 index 0000000..2652f5f --- /dev/null +++ b/0606/name.txt @@ -0,0 +1 @@ +cc \ No newline at end of file diff --git a/0606/pormise2.js b/0606/pormise2.js new file mode 100644 index 0000000..080a342 --- /dev/null +++ b/0606/pormise2.js @@ -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); + }); + } + }); + } +} \ No newline at end of file diff --git a/0606/promise.js b/0606/promise.js new file mode 100644 index 0000000..2592b4f --- /dev/null +++ b/0606/promise.js @@ -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) + }) + } + */ \ No newline at end of file diff --git a/0606/test.js b/0606/test.js new file mode 100644 index 0000000..4e142c6 --- /dev/null +++ b/0606/test.js @@ -0,0 +1,24 @@ +// const Promise = require('./promise') + + +let p = new Promise((resolve, reject) => { + setTimeout(() => { + resolve('hhh') + }) +}) + +let p2 = new Promise(r => { + r('llll') +}) + +// p.then(() => { +// return 11 +// }).then(res => { +// return new Promise(a => { +// a(res+22) +// }) +// }).then(res => console.log(res), err=> console.log(err.message)) + +// let p2= p.then(() => {return p2}) +// p2.then(res => {console.log('r',res)}, err => console.log(err)) +Promise.race([p,2,p2,1]).then(res => console.log(res)) \ No newline at end of file diff --git a/better-scroll/1.js b/better-scroll/1.js new file mode 100644 index 0000000..14269db --- /dev/null +++ b/better-scroll/1.js @@ -0,0 +1,17 @@ +const CryptoJS = require('crypto-js') +const fs = require('fs') + +const data = 'RzRaVE9PSldJVTNUSU4yQ0dNMkRHTUpXSVkzVENNWlpHTVlUR01aVEc0WkVJTlNGRzRaREdOQlRHVVpFSU1aVUc0WURNUkpUSEFaRUlNWlpHTTRUT01CVEdVWkVJTlpTRzRZVEdOUlRHRVpURU1aVkdNWVRHTVpUR1VaVFFOWlRHTTRET1JBPQ' +let baseResult=CryptoJS.enc.Base64.parse(data) +// var parsedWordArray = cr.enc.Base64.parse(data); +var parsedStr = baseResult.toString(CryptoJS.enc.Utf8); +console.log("parsed:",parsedStr); +// console.log(baseResult) +// fs.writeFile('./1.txt', baseResult, (err) => { +// if(err) { +// console.log(err) +// } +// }) + +// var test = CryptoJS.enc.Base64.parse("1ffffffff5a8ae57"); +// console.log(CryptoJS.enc.Base64.stringify(test)); \ No newline at end of file diff --git a/better-scroll/1.txt b/better-scroll/1.txt new file mode 100644 index 0000000..48a4376 --- /dev/null +++ b/better-scroll/1.txt @@ -0,0 +1 @@ +47345a544f4f4a5749553354494e3243474d3244474d4a5749593354434d5a5a474d5954474d5a5447345a45494e534647345a44474e425447555a45494d5a55473459444d524a5448415a45494d5a5a474d34544f4d425447555a45494e5a5347345954474e525447455a54454d5a56474d5954474d5a5447555a54514e5a54474d34444f52413d \ No newline at end of file diff --git a/better-scroll/package-lock.json b/better-scroll/package-lock.json new file mode 100644 index 0000000..d5cdf9e --- /dev/null +++ b/better-scroll/package-lock.json @@ -0,0 +1,23 @@ +{ + "name": "better-scroll", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "crypto": { + "version": "1.0.1", + "resolved": "https://registry.npm.taobao.org/crypto/download/crypto-1.0.1.tgz", + "integrity": "sha1-KvG3ytgXXSTIobB3glV5SiGAMDc=" + }, + "crypto-js": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-4.0.0.tgz", + "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" + }, + "cryptojs": { + "version": "2.5.3", + "resolved": "https://registry.npm.taobao.org/cryptojs/download/cryptojs-2.5.3.tgz", + "integrity": "sha1-kJVH7PFbrEVuJ1RZs58u9F1/y7k=" + } + } +} diff --git a/better-scroll/package.json b/better-scroll/package.json new file mode 100644 index 0000000..a59daf5 --- /dev/null +++ b/better-scroll/package.json @@ -0,0 +1,17 @@ +{ + "name": "better-scroll", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "crypto": "^1.0.1", + "crypto-js": "^4.0.0", + "cryptojs": "^2.5.3" + } +}