异步
function getSomething(){
setTimeout(function(){
return 'hello'
})
}
let something = getSomething()
console.log(something)//undefined
//此处不是因为setTimeout没标时间,而是因为getSomething没有return,因此是undefinded
怎么拿到setTimeout里面的返回值:‘hello’
function getSomething(){
return setTimeout(function(){
return 'hello'
})
}
let something = getSomething()
console.log(something) //64或其它数值
返回值依然是undefined
setTimeout()方法的返回值是一个唯一的数值,这个数值有什么用呢?
如果你想要终止setTimeout()方法的执行,那就必须使用 clearTimeout()方法来终止,而使用这个方法的时候,系统必须知道你到底要终止的是哪一个setTimeout()方法(因为你可能同时调用了好几个 setTimeout()方法),这样clearTimeout()方法就需要一个参数,这个参数就是setTimeout()方法的返回值(数值),用这个数值来唯一确定结束哪一个setTimeout()方法。
为什么异步函数返回的是undefined:
因为函数的结果处于setTimeout、Ajax、AddEventListener这三个的内部
异步函数与时间有关 当前排队然后去干别的事,不能直接拿到结果(可选择console.log打印,此处是为了讲解回调,重点是拿到结果)
function getSomething(){
setTimeout(function(){
console.log('hello')
})
}
let something = getSomething()
console.log(something)
//undefined
//hello
function j(){
setTimeout(()=>{
return parseInt(Math.random()*6)+1
},1000)
}//函数的返回值事undefined,setTimeout前加return则为数值
要拿到1-6的返回值,需要当前的值当前输出(找个中介进入setTimeout里,在条件满足时输出值)
所以需要使用回调函数:满足什么条件(条件是当过了1s,把值传到外部)时回头调用
function j(fn){
setTimeout(()=>{
fn(parseInt(Math.random()*6)+1
},1000)
}
function f1(x值){
console.log(x值)
}
j(f1)
j函数中的setTimeout得到结果后把结果作为参数传给f1
由于f1声明之后只用了一次,所以可简化为
function f1(x值){
console.log(x值)
}
j(f1)
j=(x)=>{
console.log(x)
}//这里的箭头函数是声明,正确调用的是下面这步
j((x)=>{
console.log(x)
})
//可再简化为j(console.log)
//如果参数个数不一致就不能这样简化
//如j((x,y)=>{
// console.log(x)
//})
异步任务不能拿到结果,于是传一个回调给异步任务
异步函数为了得到setTimeout结果,把结果作为参数传给回调:setTimeout(()=>{ fn (parseInt(…)+1
},1000) })
在promise中相当于
return new Promise((resolve,reject)=>{
resolve ( 异步要拿的结果 )
})
resolve、reject会再去调用.then成功、失败的函数
面试题拓展
箭头函数的错误简化
const array = ['1','2','3'].map(parseInt)
console.log(array)
//[1,NaN,NaN]
分析
const array = ['1','2','3'].map((1,2,3)=>{parseInt(1,2,3)})
//上行代码错误,要分析parseInt了几个参数,得看map传了什么参数,MDN中map会传三个参数(item,index,arr)
//简化后的还原应是
const array = ['1','2','3'].map((item,i,arr)=>{return parseInt(item,i,arr)})
console.log(array)
//想要得到parseInt(1)\parseInt(2)\parseInt(3)的写法应是
const array = ['1','2','3'].map((item,i,arr)=>{return parseInt(item)})
console.log(array)
//或者.map(item =>{parseInt(item)})
//若简化,则parseInt操作的值相当于(item,i,arr),代码含义改变
第一次调用为parseInt('1',0,arr)
parseInt只接受两个参数,因此arr直接忽略
传0相当于无效的参数,所以结果为1
第二次调用为parseInt('2',1,arr)
传1相当于把2作为1进制的数进行解析,2进制0、1,1进制只有0,所以得到NaN
第二次调用为parseInt('3',2,arr)
得到NaN