-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
9 - Promise #9
Comments
题
题 1new Promise(resolve => {
console.log(1)
resolve(3)
console.log(4) // ?? 为什么这个会被执行
})
.then(num => console.log(num))
console.log(2)
// 结果: 1, 4, 2, 3 题 2new Promise((resolve, reject) => {
console.log(1) // 会执行
resolve(3) // 只会走这里
reject(300000)
console.log(4) // 会执行
})
.then(
num => console.log('success', num),
num => console.log('error', num),
)
console.log(2)
// 1, 4, 2, success 3 题 3🔥 非常的 ~ 有必要 多看 new Promise((resolve, reject) => {
console.log(1)
resolve(3)
reject(300000)
Promise.resolve().then(() => console.log(4))
})
.then(
num => console.log('success', num),
num => console.log('error', num),
)
console.log(2)
// 1, 2, 4, success 3 🔥 题 4
new Promise ((resolve, reject) => {
resolve(1)
reject(2)
resolve(3)
console.log(4) // 先输出4
return new Promise((resolve, reject) => {
console.log('4-1')
// 直接执行 '4-1'
// 没有resolve 不会then下去
}).then(data => {
console.log(data)
resolve('4-1-1')
})
})
.then(
data => console.log('resolve', data),
reason => console.log('reject', reason),
)
.catch(
err => console.log('catch', err)
)
// 4, 4-1, resolve 1 题 5上层嵌套里的先被执行 new Promise ((resolve, reject) => {
resolve(1) // 1-then放到 microqueue队列中, 等待执行
reject(2)
resolve(3)
console.log(4) // 输出1: 4
return new Promise((resolve, reject) => { // 遇到Promise立刻执行
console.log('4-1') // 输出2: 4-1
resolve('from 4-1') // 放入队列中
}).then(data => {
console.log(data) // 输出3: from 4-1
resolve('4-1-1') // ???? 没有后续了 废弃
})
})
.then(
data => console.log('resolve', data), // 输出4: resolve 1
reason => console.log('reject', reason),
)
.catch(
err => console.log('catch', err)
)
// 4, 4-1, from 4-1, resolve 1 题 6setTimeout(function() {
console.log(1)
}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve(); // 这个是个同步任务哦~
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);
// 2, 3, 5, 4, 1 题 7没有resolve 就不会继续then下去, return 相当于resolve Promise.resolve(1)
.then((res) => {
console.log(res)
return 2; // 会继续往下面传递 resolve(2)
})
.catch((err) => { return 3; })
.then((res) => { console.log(res); return 4})
.then((res) => { console.log(res); })
.then((res) => { console.log(res); }) // 没有从上面传下来的值 undefined
// 1, 2, 4, undefined 题 8Promise.then 是一定要 传函数的, 如果不是函数, 就会发生值穿透现象。 Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log) 题 9 🔥const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000);
});
const promise2 = promise1.then(() => {
throw new Error('error!!!');
});
console.log('promise1', promise1);
console.log('promise2', promise2);
// 🔥
setTimeout(() => {
console.log('promise1', promise1);
console.log('promise2', promise2);
}, 2000); |
并行异步 Promise.allfunction _Promise_ () {}
_Promise_.all = function (queue) {
let result = []
let count = 0
return new Promise((resolve, reject) => {
queue.forEach((q, index) => {
q
.then(data => {
result[index] = data
count += 1
if (count === queue.length) { resolve(result) }
})
.catch(err => reject(err))
})
})
} var p1 = new Promise((resolve) => { setTimeout(() => { console.log(3000); resolve(3000) }, 3000) })
p2 = new Promise((resolve) => { setTimeout(() => { console.log(0); resolve(0) }, 0) })
// p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log(5000); reject(5000) }, 5000) })
p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log(5000); resolve(5000) }, 5000) })
_Promise_.all([p1, p2, p3]).then(data => {
console.log(data)
}).catch((err) => {
console.log('error', err)
}) |
实现 Promise.race TODO 如何停止其他请求呢?function PromiseRace (queue) {
// 谁先返回用谁
return new Promise((resolve, reject) => {
// queue.forEach(q => {
// q
// .then(data => resolve(data))
// .catch(err => reject(err))
// })
// 同上
queue.forEach(q => q.then(resolve).catch(reject))
})
} var p1 = new Promise((resolve) => { setTimeout(() => { console.log(3000); resolve(3000) }, 3000) })
p2 = new Promise((resolve) => { setTimeout(() => { console.log(0); resolve(0) }, 0) })
// p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log(5000); reject(5000) }, 5000) })
p3 = new Promise((resolve, reject) => { setTimeout(() => { console.log(5000); resolve(5000) }, 5000) })
PromiseRace([p1, p2, p3])
.then(data => { console.log('返回结果成功', data) })
.catch(error => { console.log('返回结果失败', error) }) |
实现 异步串行A => B => C => D // 串行机制
new Promise((resolve) => {
setTimeout(() => {
resolve(1000)
}, 1000)
}).then((data) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(data + 1000)
}, data + 1000)
})
}).then((data) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(data + 1000)
}, data + 1000)
})
}) 🔥 reduce 实现 前面.then(后面)// 实现串行异步, 从上面传值往下
function serial (queue) {
queue.reduce((accumulator, current) => {
// 一样效果 return accumulator.then(data => current(data))
return accumulator.then(current)
}, Promise.resolve(1000))
// queue.reduce((prev, next) => prev.then(next), Promise.resolve(0))
} // 测试
var p1 = timer => new Promise((resolve) => {
setTimeout(() => {
console.log(timer)
resolve(timer + 1000)
}, timer + 1000)
})
serial([p1, p1, p1]) = |
实现 Promise.catch/**
* 实现 Promise.catch
* 目标: 只接受reject, 是 Promise.reject的语法糖
*/
Promise.reject(1)
.then(
data => console.log('onResolved', data),
// 这里写的话, reject是匹配到了 onRejected, 不写的话 匹配到catch里面
// err => console.log('onRejected', err)
)
.catch(err => console.log('onCatch', err)) Promise.reject 的语法糖 Promise.prototype._catch_ = function (callback) {
return this.then(null, callback)
} |
实现 Promise.finally/**
* 实现 Promise.finally
* 目标: 走个过场, 将值传递给下面 无论成功或失败, 值会直接穿透到下面去
*/
Promise.reject(1)
.then(
data => console.log('onResolved', data),
// 这里写的话, reject是匹配到了 onRejected, 不写的话 匹配到catch里面
// err => console.log('onRejected', err)
)
.finally(data => console.log('finally 只是为了传值', data)) // undefined
.catch(err => console.log('onCatch', err)) Promise.resolve 和 Promise.reject 语法糖 Promise.prototype._finally_ = function (callback) {
// 返回一个 Promise
let P = this.constructor
// 先去执行callback, 之后将值传给下个 promise
return this.then(
data => P.resolve(callback()).then(() => data),
reason => P.resolve(callback()).then(() => { throw reason })
)
} |
Promise Iclass Promise {
constructor (executor) {
this.status = 'PENDING'
this.value = null
this.reason = null
this.resolveCallbacks = []
executor(this._resolve.bind(this))
}
_resolve (value) {
if (this.status === 'PENDING') {
this.value = value // 保存结果
this.status = 'FULFILLED' // 更新状态
console.log('resolveCallbacks', this.resolveCallbacks)
this.resolveCallbacks.forEach(q => q(value)) // 执行回调
}
}
then (onResolvedFn) {
if (this.status === 'PENDING') { // 将回调值放到回调队列中, 待执行
this.resolveCallbacks.push(onResolvedFn)
} else {
// 执行
onResolvedFn(this.value)
}
return this
}
} 先去执行异步事件, then里面内容先去注册到队列中, 等着resolve后, 再去执行注册队列。 let p = new Promise(resolve => {
console.log('同步执行');
setTimeout(() => { resolve('开始执行回调了') }, 2000) // 1. 异步事件, 会去执行, 等待resolve
}).then(tip => { // 2. 还没有执行resolve, pending状态, 先去将回调函数放入队列中
console.log('then1', tip);
}).then(tip => { // 3. 同上
console.log('then2', tip);
});
/**
* 4. 此时 this.resolveCallbacks = [f, f] 两个待执行
* 5. 等到2s后, resolve(开始执行回调了)
* 6. this.resolveCallbacks被执行
* 7. 两个then有相同的输出, 是 '开始执行回调了'
*/ 问题: 仅一个promise对象实例 再怎么then下去 返回的是一个结果,因为value已经存下来了解决: 每次then都是 return new Promise 就好 新的实例 |
|
Promise 实现
class Promise {
constructor (executor) {
this.status = 'PENDING'; // 初始化状态声明 PENDING RESOLVED REJECTED
this.data = null; // 成功值
this.reason = null; // 失败值
this.resolvecbQueue = []; // 成功回调队列
this.rejectcbQueue = []; // 失败回调队列
executor(this._resolve.bind(this), this._reject.bind(this))
}
// 静态方法 Promise.resolve
static resolve (value) {
if (value instanceof Promise) return value
return new Promise(resolve => resolve(value))
}
// 静态方法 Promise.reject
static reject (reason) {
return new Promise((resolve, reject) => reject(reason))
}
static all (queue) {
return new Promise ((resolve, reject) => {
var result = [], count = 0
queue.forEach((q, i) => {
q.then(d => {
result[i] = d
count += 1
if (count === queue.length) {
resolve(result)
}
})
})
})
}
static race (queue) {
return new Promise (resolve => {
queue.forEach((q) => {
q.then(d => resolve(d))
})
})
}
// p.catch((err) => console.log(err))
// 交给 _reject, 执行回调
catch (onRejected) {
return this.then(null, onRejected)
}
// 过一下, 不做任何处理, 状态都是 resolve
finally (callback) {
return this.then(
value => Promise.resolve(callback()).then(() => value),
reason => Promise.resolve(callback()).then(() => reason)
)
}
_resolve (data) {
// 异步结束了, 开始执行回调了
if (this.status === 'PENDING') {
this.data = data
this.status = 'RESOLVED'
this.resolvecbQueue.forEach(q => q(data))
}
}
_reject (reason) {
if (this.status === 'PENDING') {
this.reason = reason
this.status = 'REJECTED'
this.rejectcbQueue.forEach(q => q(reason))
}
}
then (onResolvedFn, onRejectedFn) {
onResolvedFn = typeof onResolvedFn === 'function' ? onResolvedFn : function (value) {}
onRejectedFn = typeof onRejectedFn === 'function' ? onRejectedFn : function (reason) {}
// 还没有resolve, 只能先保存注册内容
if (this.status === 'PENDING') {
return new Promise((resolve, reject) => {
this.resolvecbQueue.push(value => {
var ret = onResolvedFn(value)
if (ret instanceof Promise) {
ret.then(resolve, reject)
} else {
resolve(value)
}
})
// 同理 this.rejectcbQueue.push(reason => onRejectedFn(reason));
})
}
// 状态变了 直接执行, 另外需要then下去
if (this.status === 'RESOLVED') {
return new Promise((resolve, reject) => {
var ret = onResolvedFn(this.data)
if (ret instanceof Promise) {
ret.then(resolve, reject)
} else {
resolve(this.data)
}
})
}
if (this.status === 'REJECTED') {
return new Promise((resolve, reject) => {
var ret = onRejectedFn(this.reason)
if (ret instanceof Promise) {
ret.then(resolve, reject) // 继续then下去
} else {
reject(this.reason) // 直接返回数据
}
})
}
}
} let p = new Promise(resolve => {
console.log('#同步执行');
setTimeout(() => { resolve('1') }, 2000)
}).then(data => {
console.log('#then1#', data);
return new Promise(resolve => {
setTimeout(() => { resolve('2' + data) }, 2000)
}).then(data => new Promise(resolve => {
console.log('#then2#', data);
setTimeout(() => { resolve('3' + data) }, 1000)
}))
}).then(data => {
console.log('#then3#', data);
return data
}).then(data => {
console.log('#then4#', data);
}) Promise.resolve(1000).then(d => new Promise(resolve => {
console.log(d)
setTimeout(() => { resolve(2000 + d) }, 1000)
})).then(console.log) |
H5 Node AI DtoCode |
补充一下promise的实现:
这种改法可以解决下面这个例子:
这种改法不能解决下面这个例子:
另外一种能通过PromiseA+的实现,也可以参考这位大佬的实现 通过PromiseA+测试的Promise实现 |
作业帮 promise.race 当得知返回 如何停止掉其他的请求 写代码
阿里一面
🔥🔥🔥🔥🔥The text was updated successfully, but these errors were encountered: