async、await该如何改写官方的assetManager.loadRemote?

//加载远程的图片
export let loadRemotePic = function (fileName: string, callbackFunc?: (sf: SpriteFrame, err: any) => any) {
    let remoteUrl = "http://www.aa.com"
    assetManager.loadRemote<ImageAsset>(remoteUrl, function (err: Error, imageAsset: ImageAsset) {
        let sf = new SpriteFrame();
        let texture = new Texture2D();
        texture.image = imageAsset;
        sf.texture = texture;
        if (callbackFunc) {
            callbackFunc(sf, err);
        }
    });
}

如上,我不希望assetManager.loadRemote采用回调的方式加载头像,代码一多容易陷入地狱级别的死亡回调,实际上目前我的回调层数已经超过6层,但是即使只有6层,我也快难以维护,非常头大,有老友知道如何改写让他支持async、await这样的同步写法,而不是采用回调方式吗?
我想过很多种改法,但是发觉还是得官方支持才行,不然没法封装成async的函数,是我ts能力不足还是什么原因?
我的诉求是希望改成这样去调用:

async function getTitle(url) {
  let response = await fetch(url);
  let html = await response.text();
  return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"
1赞

查了下腊鸭,似乎才是符合我的想法的api,从这里可以看得出跟腊鸭的api有点差距啊

可以自己封装一个

求指教,真的不会

export let loadRemotePic = (fileName: string) => {
  return new Promise((resolve, reject) => {
    let remoteUrl = "http://www.aa.com";
    assetManager.loadRemote<ImageAsset>(remoteUrl, (err: Error, imageAsset: ImageAsset) => {
        if(err){
          reject(err);
          return;
        }
        let sf = new SpriteFrame();
        let texture = new Texture2D();
        texture.image = imageAsset;
        sf.texture = texture;
        resolve(sf);
    });
  });
}
3赞

类似这样吧?

2赞

你这个也是回调的方式,非async、await同步写法

他这cb回调只是用来做进度刷新而已,完成的回调是通过Promise对象了,能用async和await的。

1赞

哦哦,好的,学到了,多谢大佬,你的解决方案是正确的,看来我的ts水准不咋地,下面给出完整一点的代码,供后人参考,更改维护起来再也不用担心死亡回调了。多谢啦!

//生命周期start也能改为async,厉害
    async start() {
        await this.fetchSf1();
        await this.fetchSf2();
    }

    async fetchSf1() {
        let remoteUrl = "http://localhost:8080/static/img/m1/m1.png";
        try {
            let sf = await this.loadRemotePic(remoteUrl);
            console.log("成功");
            this.node.getComponent(Sprite).spriteFrame = sf;
            this.node.getComponent(UITransform).setContentSize(sf.rect.width, sf.rect.height);
        } catch (error) {
            console.log("失败");
        }
        await new Promise((resolve) => {
            setTimeout(resolve, 5000);
        });
        console.log("fetchSf1结束");
    }

    async fetchSf2() {
        let remoteUrl = "http://localhost:8080/static/img/m2/m2.png";
        try {
            let sf = await this.loadRemotePic(remoteUrl);
            console.log("成功");
            this.node.getComponent(Sprite).spriteFrame = sf;
            this.node.getComponent(UITransform).setContentSize(sf.rect.width, sf.rect.height);
        } catch (error) {
            console.log("失败");
        }
        await new Promise((resolve) => {
            setTimeout(resolve, 5000);
        });

        console.log("fetchSf2结束");
    }



    async loadRemotePic(remoteUrl: string): Promise<SpriteFrame> {
        return new Promise((resolve, reject) => {
            assetManager.loadRemote<ImageAsset>(remoteUrl, (err: Error, imageAsset: ImageAsset) => {
                if (err) {
                    reject(err);
                    return;
                }
                let sf = new SpriteFrame();
                let texture = new Texture2D();
                texture.image = imageAsset;
                sf.texture = texture;
                resolve(sf);
            });
        });
    }

建议原子化点:


async loadRemotePic(remoteUrl: string): Promise<SpriteFrame> {
  const imageAsset = await loadRemote<ImageAsset>(remoteUrl);
  const sf = new SpriteFrame();
  const texture = new Texture2D();
  texture.image = imageAsset;
  sf.texture = texture;
  return sf;
}

/* Promise 化 `assetManager.loadRemote`,加载任意资源 */
function loadRemote<T extends Asset>(url: string) {
  return new Promise<T>((resolve, reject) => {
    assetManager.loadRemote<T>(url, (err, asset) => {
      if (err) {
        reject(err);
      } else {
        resolve(asset);
      }
    });
  });
}
3赞

阔以阔以,我ts水平不够,写不出你这么优秀的语法