资料:
实习导师的博客:https://www.cnblogs.com/YikaJ/p/4468987.html
es6 知识: http://es6.ruanyifeng.com
this 问题: https://juejin.im/post/59bfe84351882531b730bac2
Promise 基础教学: https://www.imooc.com/learn/949
Promise/A+规范原文: https://promisesaplus.com/
Promise/A+规范译文: http://www.ituring.com.cn/article/66566
参考文章 BAT 前端经典面试问题:史上最最最详细的手写 Promise 教程: https://juejin.im/post/5b2f02cd5188252b937548ab
参考文章 手写实现满足 Promise/A+ 规范的 Promise: https://www.jianshu.com/p/8d5c3a9e6181
vscode 编辑器: https://code.visualstudio.com/
vscode 代码运行插件 code-runner: https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner
promise
主要是解决callback中的回调地狱问题。
1.基础概念
/* 1 打印hh
2 timeout结束,打印h1,参数sss
3 由于下面返回的全都是实例w,w在一开始已经执行完,所以
在w.then之后的return w,和之后的w.then return w,都是同时执行的。
*/
var w = new Promise((resolve,reject)=>{
console.log("hh")
setTimeout(()=>{
resolve("dd")
},3000)
})
w.then((sss)=>{
console.log('h1',sss)
return w
})
.then((a)=>{
console.log("h2",a)
return w
})
比较两者。
/* 1 打印hh
2 timeout 3s结束,打印h1,'dd' 'aaa'
3 timeout 1s结束,打印'h2,asdf'
*/
var w = new Promise((resolve,reject)=>{
console.log("hh")
setTimeout(()=>{
resolve("dd")
},3000)
})
w.then((sss)=>{
console.log('h1',sss)
return new Promise((resolve,reject)=>{
console.log('aaa')
setTimeout(() => {
resolve('asdf')
}, 1000);
})
})
.then((a)=>{
console.log("h2",a)
return w
})
Promise/A+ 规范
见译文:http://www.ituring.com.cn/article/66566
项目实战笔记
1.为防止提示undefined:
data && JSON.parse(data)
2.如果一个函数
async function eat(){
TV.on('close',()=>{
//TODO
}
return await TVclosing()
}
即在函数eat()中,有异步的TVclosing,又需要监听TV.on,且TVclosing又需要进入TV.on进行判断,则:可以:
function eat(){
return new Promise(async (resove,reject) =>{
let state : Record<string, any>
TV.on('close',()=>{
if(state)resolve(true)
else resolve(false)
}
try{
await TVclosing()
}catch(e)
{
resolve(false)
}
}
}
手写Promise
可参考:https://www.bilibili.com/video/BV1av411q7sb?spm_id_from=333.337.search-card.all.click
https://juejin.cn/post/6850037281206566919
https://zh.javascript.info/promise-chaining
/**
* 1. new Promise((resolve, reject) => {}),两个入参,且方法错误直接reject
* 2. 有3种状态,pending -> fullfiled/rejected
* 3. .then(onFULLFILTED, onREJECTED):(1)函数/非函数判断 (2) 可以是异步的 (3) then是异步的
* 4. resolve和reject是事件执行最后才执行的。即需要有setTimeout(()=> {resolve()})
* 5. .then 返回新的Promise
* 5.1 return的是非函数
* 5.2 return的是异步函数/非异步函数
* 6. 在所有可能出现问题的地方加try/catch,例如第1点,方法错误直接reject,其他下面先不加try/catch,显得太乱
*/
const handlePromise = (result, promise2, resolve, reject) => {
// 自己等待自己完成是错误的实现
if(result === promise2) {
throw new Error('cannot return oneself')
}
if(typeof(result) === 'object' && result !== null || typeof(result) === 'function' ) {
if(typeof(result.then) === 'function') {
result.then.call(result, r => handlePromise(r, promise2, resolve, reject), e => reject(e))
} else {
resolve(result)
}
} else {
resolve(result)
}
}
class Promise {
static PEDDING = '执行'
static FULLFILED = '成功'
static REJECTED = '失败'
status = Promise.PEDDING
value = undefined
reason = undefined
cbFULLFILEDLIST = []
cbREJECTEDLIST = []
constructor(callback) {
this.status = Promise.PEDDING
try {
callback(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject.bind(this)(error)
}
}
resolve(value) {
if (this.status === Promise.PEDDING) {
this.status = Promise.FULLFILED
}
this.value = value
this.cbFULLFILEDLIST.forEach(cb => cb())
}
reject(reason) {
if (this.status === Promise.PEDDING) {
this.status = Promise.REJECTED
}
this.reason = reason
this.cbREJECTEDLIST.forEach(cb => cb())
}
then(onFULLFILTED, onREJECTED) {
onFULLFILTED = typeof (onFULLFILTED) === 'function' ? onFULLFILTED : () => { }
onREJECTED = typeof (onREJECTED) === 'function' ? onREJECTED : () => { }
const promise2 = new Promise((resolve, reject) => {
if (this.status === Promise.FULLFILED) {
setTimeout(() => {
const result = onFULLFILTED(this.value)
handlePromise(result, promise2, resolve, reject)
})
}
if (this.status === Promise.REJECTED) {
setTimeout(() => {
const result = onREJECTED(this.reason)
handlePromise(result, promise2, resolve, reject)
})
}
if (this.status === Promise.PEDDING) {
this.cbFULLFILEDLIST.push(() => {
setTimeout(() => {
const result = onFULLFILTED(this.value)
handlePromise(result, promise2, resolve, reject)
});
})
this.cbREJECTEDLIST.push(() => {
setTimeout(() => {
const result = onREJECTED(this.reason)
handlePromise(result, promise2, resolve, reject)
});
})
}
// })
})
return promise2
}
}
console.log('Step 1');
const promise = new Promise((resolve, reject) => {
console.log('Step 2')
// reject('error 我出来了')
console.log('Step 4')
setTimeout(() => {
resolve('我出来了')
}, 1000);
}).then((res) => {
console.log('then 1', res)
}).then(res => {
console.log('then 2')
})
console.log('Step 3');