使用Typescript延迟加载模式

Fox*_*Fox 6 javascript design-patterns lazy-loading typescript

因此,使用C#和其他语言,您可以在属性上获取和设置评估器,构建延迟加载模式非常简单.

我最近才开始玩Type Script而且我正在努力实现同样的目标.我正在通过Ajax Call加载Poco的大部分属性.问题可以描述如下:

export interface IDeferredObject<T> {
    HasLoaded: boolean;
    DeferredURI: string;         
}

export class Library{        

    LibraryName: string;
    Books: IDeferredObject<Book[]>;        
}   

export class Book {
    Title: string;
    UniqueNumber: number;
}



window.onload = () => {
    //Instantiate new Library
    var lib = new Library();

    //Set some properties
    lib.LibraryName = "Some Library";

    //Set the Deferred URI Rest EndPoint
    lib.Books.DeferredURI = "http://somerestendpoint";
    lib.Books.HasLoaded;      



    //Something will trigger a  GET to lib.Books which then needs to load using the Deferred Uri       

};
Run Code Online (Sandbox Code Playgroud)

几个问题:我

  • 接口在这里使用是否正确?
  • 当某些内容访问Library Books Property时,我想触发Load操作.这甚至可能吗?

我知道这是一个非常开放的问题,只是寻找关于如何构建该模式的一些指导.

谢谢

Ale*_*kiy 5

Books可以声明为属性(请参阅在TypeScript中获取和设置),在其getter中,您可以启动ajax调用.唯一的问题是你无法知道何时ajax调用将返回,并且你不想在Books加载值时阻止代码执行.您可以使用承诺来解决您的问题.以下代码使用通过调用返回的JQuery Deferred Object$.ajax(自1.5版本起).

一个变化 - HasLoadedDeferredURI.它们应该驻留在"loader类"中,Library因为在我的示例中,Library类负责数据检索.

export class Library {
    private _loadedBooks: Book[];
    public get Books(): any {
        var result: any = null;
        // Check first if we've already loaded values from remote source and immediately resolve deferred object with a cached value as a result
        if(this.HasLoaded) {
            result = $.Deferred();
            result.resolve(this._loadedBooks);
        }
        else {
            // Initiate ajax call and when it is finished cache the value in a private field
            result = $.ajax(this.DeferredURI)
                          .done((values) => {
                              this.HasLoaded = true;
                              this._loadedBooks = values; 
                          });
        }
        return result;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后代码使用者将使用Books如下:

var library = new Library();
library.Books.done((books: Book[]) => {
    // do whatever you need with books collection
});
Run Code Online (Sandbox Code Playgroud)

对我来说,这种设计是反直觉的,并且此代码的​​用户不希望Books字段/属性返回延迟对象.所以我建议把它改成方法,比如loadBooksAsync().此名称将指示此方法中的代码是异步的,并且暗示返回值是延迟对象,该值将在稍后的某个位置可用.