一、setTimeout函数
JavaScript是单线程语言,但是它可以通过设置超时值和间歇时间值来指定代码在特定的时刻执行。超时值是指在指定时间之后执行代码,间歇时间值是指每隔指定的时间就执行一次代码。
延时执行,改变函数的执行顺序,并不是异步操作
可以写成字符串参数的形式,由于这种形式会造成javascript引擎两次解析,降低性能,故不建议使用
第二个参数是一个表示等待多长时间的毫秒数,如果省略setTimeout的第二个参数,则该参数默认为0,但是在该时间过去后代码并不一定执行。JavaScript是一个单线程序的解释器,因此一定时间内只能执行一段代码。为了控制要执行的代码,就有一个JavaScript任务队列。这些任务会按照将它们添加到任务队列的顺序执行。setTimeout()的第二个参数告诉JavaScript再过多长时间把当前任务添加到队列中。如果队列是空的,那么添加的代码则会立即执行;如果队列不是空的,那么添加的代码会在前面的代码执行完毕后再执行。
var aa="aaaaValue";
var bb="bbbbValue";
setTimeout(function(arg1,arg2){
alert(arg1+"---"+arg2);//匿名函数的形参,局部变量
alert(aa+"---"+bb);//全局变量
},0,aa,bb);//后面传递参数
var aa={"aa":"bbbb"};
setTimeout((function(arg){
alert(arg.aa);
})(aa),3000);//相当于传入下面的表达式,之后立即调用,不设定延迟,延迟多少都会立即调用
相当于
setTimeout(alert(aa.aa),3000);
setTimeout('alert(aa.aa)',3000);//这个才具有延时效果,延迟3秒执行
setTimeout((function(a,b){
return function(){
alert(a+b);
}
})(1,9),1000);//立即执行函数返回一个函数对象,1秒后将返回的函数对象放入任务队列
二、回调函数
因为函数在Javascript中是第一类对象,我们像对待对象一样对待函数,因此我们能像传递变量一样传递函数,在函数中返回函数,在其他函数中使用函数。当我们将一个回调函数作为参数传递给另一个函数是,我们仅仅传递了函数定义。我们并没有在参数中执行函数。我们并不传递像我们平时执行函数一样带有一对执行小括号()的函数。
需要注意的很重要的一点是回调函数并不会马上被执行。它会在包含它的函数内的某个特定时间点被“回调”(就像它的名字一样)。
- 使用命名或匿名函数作为回调
//全局变量
var allUserData = [];
//普通的logStuff函数,将内容打印到控制台
function logStuff (userData){
if ( typeof userData === "string")
{
console.log(userData);
}
else if ( typeof userData === "object"){
for(var item in userData){
console.log(item + ": " + userData[item]);
}
}
}
//一个接收两个参数的函数,后面一个是回调函数
function getInput (options, callback){
allUserData.push(options);
callback(options);
}
//当我们调用getInput函数时,我们将logStuff作为一个参数传递给它
//因此logStuff将会在getInput函数内被回调(或者执行)
getInput({name:"Rich",speciality:"Javascript"}, logStuff);
//name:Rich
//speciality:Javascript
- 传递参数给回调函数
//全局变量
var generalLastName = "Cliton";
function getInput (options, callback){
allUserData.push (options);
//将全局变量generalLastName传递给回调函数
callback(generalLastName,options);
}
- 在执行之前确保回调函数是一个函数
function getInput(options, callback){
allUserData.push(options);
//确保callback是一个函数
if(typeof callback === "function"){
//调用它,既然我们已经确定了它是可调用的
callback(options);
}
}
三、回调函数this指向
var clientData = {
id: 094545,
fullName:"Not Set",
//setUsrName是一个在clientData对象中的方法
setUserName:function(firstName,lastName){
this.fullName = firstName + " " + lastName;
}
};
function getUserInput(firstName, lastName, callback){
//在这做些什么来确认firstName/lastName
//现在存储names
callback(firstName, lastName);
}
getUserInput("Barack","Obama",clientData.setUserName);
console.log(clientData.fullName); //Not Set
//fullName属性将在window对象中被初始化
console.log(window.fullName); //Barack Obama
//注意到我们增加了新的参数作为回调对象,叫做“callbackObj”
function getUserInput(firstName, lastName, callback,callbackObj){
//在这里做些什么来确认名字
callback.apply(callbackObj, [firstName, lastName]);
}
//我们将clientData.setUserName方法和clientData对象作为参数,clientData对象会被Apply方法使用来设置this对象
getUserInput("Barack", "Obama", clientData.setUserName, clientData);
console.log(clientData.fullName); //Barack Obama
//fullName属性将在window对象中被初始化
console.log(window.fullName); //undefined
四、Promise函数
构造函数Promise接受一个函数test,可以理解为传入一个异步任务,resolver接受两个参数,一个是成功时的回调,一个是失败时的回调,这两参数和通过then传入的参数是对等的。
function test(resolve, reject) {
var timeOut = Math.random() * 2;
setTimeout(function () {
if (timeOut < 1) {
resolve('200 OK');
}
else {
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});
//也可以在then里面定义失败函数,就不用catch了
// new Promise(test).then(function (result) {
// console.log('成功:' + result);
// },function(reason){
// console.log('失败:' + reason);
// });
console.log("promise结束!!!!!!!");
Promise 的api
1、Promise.resolve()
2、Promise.reject()
3、Promise.prototype.then()
4、Promise.prototype.catch()
5、Promise.all() // 所有的都有完成,相当于 且
6、Promise.race() // 完成一个即可,相当于 或
let p1 =new Promise(function(resolve,reject){
resolve(1);
});
let p2 = new Promise(function(resolve,reject){
resolve(2);
});
let p3 = new Promise(function(resolve,reject){
resolve(3);
});
Promise.all([p1, p2, p3]).then(function (results) {
console.log('success:'+results);//输出1,2,3
}).catch(function(r){
console.log("error");
console.log(r);
});
console.log("promise结束!!!!!!!");
// promise结束!!!!!!!
// success:1,2,3
Promise链式调用
var Pro = function () {
//返回一个Promise对象
return new Promise(function (resolve, reject) {
//模拟接口调用
setTimeout(function () {
resolve(true);
}, 1000);
})
};
var Pro2 = function () {
//返回一个Promise对象
return new Promise(function (resolve, reject) {
//模拟接口调用
setTimeout(function () {
resolve('Pro2成功执行');
}, 1000);
})
};
Pro().then(function(data){
var val = data;
console.log(val)
if (val) {
console.log(1111)
return Pro2()
}
}).then(function(data1){
console.log(data1)
})