js中的同步与异步(3.回调地狱)

先提一个需求:
在打开一个网页游戏时,你需要要等到三张图片全部载成功之后,才能去开始去游戏。
如果写伪代码是:

加载图片();
开始游戏();

从格式上看,这明显是一个同步的代码:加载图片()这个函数执行完成之后,才会去做 ga开始游戏() ,但现在有一个问题,加载图片这件事是异步的。

加载图片这件事本身是异步的

举个例子,你在html文件中,写如下代码:

![](图片地址1)

此时浏览器就会去请求"图片地址1"这个url中的资源。但只是发送请求而已,什么时候得到结果是不确定的。

如果是是通过js代码,我们会用如下的代码去加载图片:

var img = new Image();
img.src = "图片地址1";
img.onload = function(){
    alert("加载成功")
}
img.error = function(){
    alert("加载失败")
}

举个实际的应用例子:在网络上加载一张图片后,再用canvas画出来。
下面是错误的代码:





上面的代码错误之处在于,img.src这个属性设置之后,浏览器会去请求这张图,然后接下去执行[2],此时,img并没有请求成功,所以也不会正确地画出图像。

应该要改成:

img.src="http://img.ivsky.com/img/tupian/pre/201708/18/zhuangguanmeilidetitiantupian.jpg";
    
img.onload = function(){
    context.drawImage(img,0,0) //[2]
}

把context.drawImage写在onload事件的回调函数中。意思是:当img加载成功后,才做画图这件事。

下面我们去实现本文开头提出的需求,三张图全部加载成功后,再去做后续的工作。

var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
img1.src = "地址1";
img1.onload = function(){
    img2.src = "地址2";
    img2.onload = function(){
        img3.src = "地址3";
        img3.onload = function(){
            alert("全部加载完成!")
        }
    }
}

上面的这一串代码形式有一个专门的名字:callback hell (回调地狱)

你可能感兴趣的:(js中的同步与异步(3.回调地狱))