老师,为什么我把返回语句放在setTimeout里就会报错

老师,为什么我把返回语句放在setTimeout里就会报错

      const loadImgAsync = url => {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = url;
img.onload = () => {
resolve(img);
};

img.onerror = () => {
reject(new Error(`Could not load image at ${url}`));
};


});
};

loadImgAsync("http://img1.sycdn.imooc.com/climg//5b16558d00011ed506000338.jpg")
.then(img2=>{
document.body.appendChild(img2)
return loadImgAsync("http://img1.sycdn.imooc.com/climg//5b165603000146ca06000338.jpg")
})
.then(img=>{
setTimeout(()=>{
document.body.appendChild(img)
//放在这里会报错 return loadImgAsync("http://img1.sycdn.imooc.com/climg//5b1656140001c89906000338.jpg")
},1000)
return loadImgAsync("http://img1.sycdn.imooc.com/climg//5b1656140001c89906000338.jpg")
})
.then(img=>{
setTimeout(()=>{
document.body.appendChild(img)
},2000)
})


正在回答

登陆购买课程后可参与讨论,去登陆

3回答

同学你好, 因为将返回语句放在setTimeout中,此时return返回的结果是针对setTimeout中的回调函数,并不是针对then的,具体可以参考如下解析:

http://img1.sycdn.imooc.com//climg/606687f50996133711190301.jpg

“好帮手慕星星”老师提供的修改代码中,将定时器放在了loadImgAsync函数中,等图片成功加载,隔一秒后才将图片追加到页面中,然后执行resolve方法,将Promise对象改为成功状态的。所以只有定时器执行完之后,才会去更改Promise对象的状态。

因为在then的回调函数中没有手动添加return时,才会默认返回一个成功状态的Pomise,而老师提供的代码中,在then方法的回调中手动设置了return返回loadImgAsync,所以不会再默认返回一个成功状态的Promise了


祝学习愉快~

好帮手慕星星 2021-04-01 18:14:07

同学你好,因为定时器是异步的,但是then方法中其他语句不是,所以如果将return放在定时器中,那么下面的then拿不到传入的数据

http://img1.sycdn.imooc.com//climg/60659b92096069be07780382.jpg

http://img1.sycdn.imooc.com//climg/60659b9e09ed743001980029.jpg

也就不能将数据添加到页面中。


另外练习视频中一开始并没有默认显示第一张图,而是1s后出现的,建议修改代码,将定时器统一放在loadImgAsync方法中会方便一些,参考:

http://img1.sycdn.imooc.com//climg/60659cea09cb476f10400788.jpg

祝学习愉快!

  • 提问者 席萌萌 #1
    为什么最后一个then会同步执行,按道理他应该等待上面的then返回
    resolve();才能执行啊
    2021-04-01 18:31:15
  • 好帮手慕星星 回复 提问者 席萌萌 #2

    then是异步执行的,但是then中会默认返回一个成功状态的promise,而定时器是异步的,所以先执行了默认返回的promise,也就会没有获取到数据。

    2021-04-01 19:01:26
  • 提问者 席萌萌 回复 好帮手慕星星 #3
    那为什么老师指导我修改的代码中,then会等待loadImgAsync方法中
    setTimeout
    中的
    resolve(),而不是默认返回一个成功状态的promise
    2021-04-01 19:39:04
席萌萌 提问者 2021-04-01 17:46:23

报错的原因是:最后一个then找不到传入的img元素。

我把 倒数第二个then的返回语句

return loadImgAsync("****")

放在setTimeout里,就是想让最后一个then里的代码等到 倒数第二个then 延迟1000秒后再加载新图片然后返回

resolve();

  但是实际上,最后一个then不等倒数第二个then的setTimeout里的

resolve();


执行,他是立马执行的,所以导致了这个错误。


但是我不知道为什么会这样,请老师指点

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师