学习记录,加深印象
1. 回调函数
JavaScript是单线程,因此JavaScript中的浏览器事件、网络操作需要异步执行,而异步执行可以用回调函数实现
function callback() {
console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 1000); // 1秒钟后调用callback函数
console.log('after setTimeout()');
- callback回调函数,作为JundgeNum的参数
function JundgeNum(num,callback){
if(num<0)
return setTimeout(callback,1000,1)
setTimeout(callback,1000,null,num) //null,num表示callback的一二参数
}
JundgeNum(2,function(err,succ){
if(err)
console.log('数字小于0')
else //当callback中err参数为null时
console.log('成功,数字为'+succ)
})
console.log('test')
//test
//成功,数字为2 (1秒后出现)
- 将callback的两个参数(err,succ)拆开为两个函数来看,分别作为JundgeNum的两个参数
function JundgeNum(num,succ,err)
{
if(num<0)
return setTimeout(err, 1000)
setTimeout(succ, 1000)
}
JundgeNum(1,function(){
console.log('成功,数字大于0')
},function(){
console.log('err数字小于0')
})
console.log('test')
//test
//成功,数字大于0
2.回调地狱
回调套回调,当回调嵌套很深时,就称为回调地狱
function JundgeNum(num,succ,err){
if(num<0)
return setTimeout(err, 1000,num)
setTimeout(succ, 1000,num)
}
JundgeNum(2,function(num){
console.log(num)
JundgeNum(4,function(num){
console.log(num)
JundgeNum(3,function(num){
console.log(num)
JundgeNum(5,function(num){
console.log(num)
})
})
})
})
//4
//16
//9
//25
3.Promise
- Promise是一个构造函数,因此我们可以new Promise得到一个Promise的实例对象
- 在Promise上,有两个函数,resolve(成功之后的回调函数),reject(失败之后的回调函数)
- 在Promise构造函数的Prototype属性上,有一个.then()方法,也就是说,只要是Promise构造函数创建的实例,都可以访问到.then()方法
- 我们可以在new出来的Promise实例上,调用.then()方法,预先为这个异步操作,指定成功 (resolve)和失败(reject)回调函数
function JundgeNum(num){
return promise=new Promise(function(resolve,reject){
if(num<0) return setTimeout(reject,1000)
setTimeout(resolve,1000,num*num)
})
}
JundgeNum(-1).then(function(num){
console.log(num) //预先指定成功resolve函数
},function(){
console.log('小于0') //预先指定失败reject函数
})
//小于0
- 在上一个.then中,返回一个新的promise实例,可以继续用下一个.then处理
function JundgeNum(num){
return promise=new Promise(function(resolve,reject){
setTimeout(resolve,1000,num)
})
}
var p=JundgeNum(2)
p.then(function(num){
console.log(num)
return JundgeNum(num*num)
}).then(function(num){
console.log(num)
return JundgeNum(num*num)
}).then(function(num){
console.log(num)
})
//2
//4
//16
Promise单纯的为了解决回调地狱的问题,并不能帮我们减少代码量
廖雪峰官方网站例子
// 0.5秒后返回input*input的计算结果:
function multiply(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
}
// 0.5秒后返回input+input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
console.log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
}
var p = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(2);
});
p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result) {
console.log('Got value: ' + result);
});
Promie中捕获异常的两种方式
- 如果前面的Promise执行失败,但不想让后续的Promise操作被终止,可以为每个Promise指定失败的回调
function JundgeNum(num){
return promise=new Promise(function(resolve,reject){
if(num>0||num===0)
return setTimeout(resolve,1000,num)
setTimeout(reject,1000,num)
})
}
var p=JundgeNum(0)
p.then(function(num){
console.log(num)
return JundgeNum(num-1)
},function(err){
console.log(err+'!!数值为负')
return JundgeNum(err-1)
})
.then(function(num){
console.log(num)
return JundgeNum(num-1)
},function(err){
console.log(err+'!!数值为负')
return JundgeNum(err-1)
})
.then(function(num){
console.log(num)
},function(err){
console.log(err+'!!数值为负')
})
//0
//-1!!数值为负
//-2!!数值为负
- 如果后续的promise执行依赖于前面promsie执行的结果,因此前面失败了后面没有执行下去的意义,则立即终止所有的Promise执行,这时可用.catch()
function JundgeNum(num){
return promise=new Promise(function(resolve,reject){
if(num>0||num===0)
return setTimeout(resolve,1000,num)
setTimeout(reject,1000,num)
})
}
var p=JundgeNum(0)
p.then(function(num){
console.log(num)
return JundgeNum(num-1)
}).then(function(num){
console.log(num)
return JundgeNum(num-1)
}).then(function(num){
console.log(num)
}).catch(function(err){
console.log(err+'!!数值为负')
})
//0
//-1!!数值为负