2分钟搞定JS面试 / 承诺
问题:
什么是承诺?
快速回答:
它是一个表示操作当前状态和值的对象。Promises 有三种状态:待处理、成功、失败。
更长的答案:
基本上,Promises 背后的想法相当容易理解。它只是一个容器,只有在某些计算完成后才会解析。就是这样。
我想如果我们自己实现它就会更容易理解。
class MyPromise {
dataHandlers = []
errorHandler = []
finalHandlers = []
constructor(func) {
// Apply handlers one by one and initialize every following handler with the previouses result
let onResolve = data => this.dataHandlers.reduce(
(acc, onData) => onData(acc),
data
)
// Just call every onReject
let onReject = error => this.errorHandler.reduce(
(_, onError) => onError(error),
undefined
)
// Just call every onFinal
let onFinal = () => this.finalHandlers.reduce(
(_, onFinal) => onFinal(),
undefined
)
// We need to set timeout, so our function
// executed after we set .then, .catch, and .finally
setTimeout(() => {
try {
func(onResolve, onReject)
} catch (error) {
onReject(error)
} finally {
onFinal()
}
}, 0)
}
then(onData, onError) {
if (onData) { this.dataHandlers.push(onData) }
if (onError) { this.errorHandler.push(onError) }
return this
}
catch(onError) {
return this.then(undefined, onError)
}
finally(onFinal) {
if (onFinal) { this.finalHandlers.push(onFinal) }
return this
}
}
让我们测试一下!
let dataPromise = new MyPromise((resolve, reject) => resolve(2))
dataPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res)) // 8
.finally(() => console.log('Finally!')) // Finally!
.finally(() => console.log('Finally (1)!')) // Finally (1)!
let rejectPromise = new MyPromise((resolve, reject) => reject(2))
rejectPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res))
.catch(error => console.error(error)) // 2
.finally(() => console.log('Finally!')) // Finally!
let throwErrorPromise = new MyPromise((resolve, reject) => { throw new Error('hello') })
throwErrorPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res))
.catch(error => console.error(error)) // hello
.finally(() => console.log('Finally!')) // Finally
// This one will produce two errors instead of one.
// Can you come up with the fix?
let doubleErrorPromise = new MyPromise((resolve, reject) => reject('first'))
doubleErrorPromise
.catch(error => { console.error(error); throw 'second' })
// 'first'
// 'second'
// Uncaught 'second'
// This is how it should work
let fixedDoubleErrorPromise = new Promise((resolve, reject) => reject('first'))
fixedDoubleErrorPromise
.catch(error => { console.error(error); throw 'second' })
// 'first'
// Uncaught 'second'
实际应用:
有时使用async/await 语法会更容易一些
有时你会需要 Promise 辅助函数,例如Promise.all
资源:
MDN/Promise
其他帖子:
顺便说一句,我会在这里和推特上发布更多有趣的东西。我们做个朋友吧👋
鏂囩珷鏉ユ簮锛�https://dev.to/hexnickk/js-interview-in-2-minutes-promise-4fhl