js是单线程语言,但是它的宿主环境是多线程的。如浏览器,node。
js分为两种任务:同步任务和异步任务。同步任务是指渲染网页时的正常语法规则等;异步任务是指在渲染时遇到的资源请求、触发事件、定时器任务。
1、异步任务
当我们写程序时,遇到异步任务,js会将任务放到任务队列中,不影响主任务的运行。
具体原理可以参考这篇文章
2、Promise期约
var promise = new Promise(function(resolve, reject) {
//。。。success是指期约运行结果的反馈
if (success) {
resolve();
} else {
reject();
}
})
参数部分包括了 resolve和reject 分别对应两种状态,resolve表示成功,reject表示失败!,还有第三种等待态往后看…
看一个例子
let promise = new Promise(function(resolve, reject){
console.log("1");
reject()
console.log("2");
setTimeout(console.log("3"), 1000);
});
promise.then(() => console.log("4")).catch(()=> console.log("5"));;
console.log("6");
结果是
1
2
3
6
5
将第三行的reject方法改成resolve结果是5变成4,因为执行失败时reject会抛出一个异常。
上段代码的含义是在new一个期约时,会在住任务中执行完毕期约内的代码,最后根据结果状态执行then方法或catch方法。
promise还可以用作接口并发调用的操作,比如当我们需要同时发出三个请求,并且计算过程需要这三个借口的返回内容。
如果串联方式调用会耗费大量时间,即t1+t2+t3
。promise并发处理可以避免这种情形,时间价值是max(t1, t2, t3)
。
Promise([
$.post(..., {}),
$.post(..., {}),
$.post(..., {})
]).then(resArr => {
console.log(resArr);
});
结果resArr是三个请求的结果数组。
[res1, res2, res3]
3、async和await
async是一个声明异步函数的关键词,与await配套使用,如果await的函数在声明时没有标明async,也是不影响的,编译器会自动加注。
await根据翻译也能理解,就是等待的意思,等待函数体内执行完毕
看不懂就结合下面的代码吧。
async function say(greeting){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(greeting);
},1500);
});
}
(async function(){
var v1=await say('Hello');
console.log(v1);
var v2=await say('World');
console.log(v2);
}());
注:必须在async声明的函数中才能使用await,否则会报错
SyntaxError: await is only valid in async function
at Module._compile (internal/modules/cjs/loader.js:892:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
at internal/main/run_main_module.js:17:11
输出结果是
(1500ms)
hello
(1500ms)
world
好! 如果我们把await删掉
async function say(greeting){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(greeting);
},1500);
});
}
(function(){
var v1= say('Hello');
console.log(v1);
var v2= say('World');
console.log(v2);
}());
输出结果是
Promise { <pending> }
Promise { <pending> }
(1500ms后结束)
因为在say函数中返回的是promise期约,所以输出的是promise的等待态,这也是promise的第三态!
在执行完成后会返回resovle的值。
部分灵感来源于这里
后续更新中…