Promise本身是没有同步和异步说法的,Promise和then合用实现的是异步阻断变同步
例如:图片的加载(load)
function loadImage(src){
return new Promise(function(resolve,reject){
var img=new Image();
img.src=src;;
img.onload=function(){
resolve(img);
}
img.onerror=function(){
console.log("加载错误");
}
})
}
loadImage("./img/2-.jpg").then(function(img){
console.log(img);
return loadImage("./img/3-.jpg"); //返回Promise,所以后面跟then(链式加载)
}).then(function(img){
console.log(img);
})
解析:
1.Promise 可以看做是一个类,我们只是实例化了他,并没有执行,所以一般(注意是一般)new Promise是写在函数中使用的.
2.onload是典型的异步(具体还有哪些典型异步请看下一篇),通过图片地址的改变,触发onload事件 的执行,只有当一次onload执行完毕后,才会触发resolve,回调then的函数,进而执行后面的图片,
所以实现了异步变同步的操作
async函数执行返回的是Promise,async函数中return就会执行这个函数执行返回的promise.resolve方法
async function fn(){
return 1;
}
var a=fn();
a.then(function(value){
console.log(value);
})
解析:
1. async函数中return就会执行这个函数执行返回的promise的resolve方法,因此可以在then中获取
2.这里a.then相当于Promise.resolve().then();
async和await一般一起使用,await是强制异步阻塞,没加载完成不会执行后面的
function loadImg(src) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.src = src;
img.onload = function () {
resolve(img);
}
})
}
async function fn(){
console.log("aaa")
await loadImg("./img/3-.jpg").then(function(img){
console.log(img)
})
console.log("bbb");
}
loadImg("./img/2-.jpg").then(function(img){
console.log(img);
})
fn();
解析: 1.我先说结果:第一种:aaa 3-.jpg bbb 2-.jpg 第二种: aaa 2-.jpg 3-,jpg bbb 2.代码是按照顺序往下执行的,loadImg和fn一直为执行,知道下面loadImg()开始执行,但是因为loadImg 里面是onload事件,上面说过onload是异步执行,所以这里2.jpg被放到任务流的下面,然后fn执行,aaa是注册事件,毫无疑问的是第一个执行,后面执行到await强制阻断onload的异步,又因为await是微任务(这里不需要理解什么是微任务,想要理解的看下一篇)放到了任务流的下面,也就是2.jpg任务的下面,然后执行2.jpg-->3.jpg-->bbb. 3.为什么会出现第一条说的两种情况呢? 是因为onload需要加载的时间,如果第一次2.jpg任务放到最下面,等到3.jpg任务放置最下面时,2.jpg还是没加载完,这时的任务执行顺序会变成3.jpg-->bbb-->2.jpg, 如果2.jpg加载完成了,那么执行顺序会变成2.jpg-->3.jpg-->bbb