js中的异步编程
为什么要异步编程?
- js是单线程的,如果一个任务很耗时,会阻塞后面的任务执行
- 看MDN中的例子:https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Asynchronous/Concepts
就前面提到的种种原因(比如,和阻塞相关)很多网页API特性使用异步代码,特别是从外部的设备上获取资源,例如,请求API获取数据,发送请求获取图片,从网络获取文件,访问数据库等
-
一个加载图片的例子:(取代的方法就是,代码必须等到
response
返回才能继续往下执行) -
var response = fetch('myImage.png'); var blob = response.blob();// 这段代码可能会报错,因为它在执行的时候不确定图片是否已经下载过来了
-
处理文件的例子
Promise解决回调函数带来的回调地狱问题(嵌套过深)
协程
如何使用Generator函数
await 后面的表达式
原理
await转化例子1
async2() 为一个普通表达式,没有返回Promise,所以要将async2用Promise包裹起来
async function async1() {
console.log('async1 start');
await async2()
console.log('async end');
}
async function async2() {
new Promise((resolve, reject) => {
console.log('async2 start');
resolve()
}).then(res => {
console.log('async2 end');
})
}
// 上面的await代码转换为下面的代码
async function async1() {
console.log('async1 start');
// await async2()
const p1 = new Promise((res, rej) => {
new Promise((resolve, reject) => {
console.log('async2 start');
resolve()
}).then(() => {
console.log('async2 end');
})
res(); // 注意这里要把p1的状态变为resolved才能执行接下来的then函数
})
p1.then(() => console.log("async end"))
return p1; // 返回一个Promise
}
async1()
new Promise(resolve => {
console.log('Promise');
resolve()
}).then(res => {
console.log('Promise end1');
})
.then(res => {
console.log('Promise end2');
})
.then(res => {
console.log('Promise end3');
})
.then(res => {
console.log('Promise end4');
})
console.log('script end');
/*
结果
async1 start
async2 start
Promise
script end
async2 end
async end
Promise end1
Promise end2
Promise end3
Promise end4
*/
await转化例子2(个人理解)
async function async1() {
console.log('async1 start');
await async2()
console.log('async end');
}
async function async2() {
return new Promise((resolve, reject) => {
console.log('async2 start');
resolve()
}).then(res => {
console.log('async2 end');
})
}
// 上面的代码会被转化为下面的代码(个人理解,可能不准确)
async function async1() {
console.log('async1 start');
// await async2()
new Promise((resolve) => {
new Promise((res,rej)=>{
console.log('async2 start');
res()
}).then(()=>{
}).then(()=>{
resolve()
})
}).then(function () {
console.log('async1 end')
});
}
async1()
new Promise(resolve => {
console.log('Promise');
resolve()
}).then(res => {
console.log('Promise end1');
})
.then(res => {
console.log('Promise end2');
})
.then(res => {
console.log('Promise end3');
})
.then(res => {
console.log('Promise end4');
})
console.log('script end');
/*
结果
async1 start
async2 start
Promise
script end
async2 end
async end
Promise end1
Promise end2
Promise end3
Promise end4
*/
参考:
https://www.ruanyifeng.com/blog/2015/04/generator.html
https://segmentfault.com/a/1190000023442526
https://www.jianshu.com/p/8547a58dcf65