我们在开发复杂的Angular应用时,经常会用到Rxjs的defer函数,例如:创建一个Observable,调用Observable工厂为每个创建的新Observer一个Observable对象。该函数接收一个输入参数,该参数是工厂函数类型。输出是一个Observable对象,一旦被订阅,它绑定的工厂函数就会被调用。defer的本质是一种延迟创建机制,即只有在返回的Observable被订阅时才会创建Observable对象。defer允许您仅在Observer订阅时创建Observable。它会等到一个观察者订阅它,调用给定的工厂函数来获取一个Observable——工厂函数通常会产生一个新的Observable——然后将Observer订阅到这个Observable。如果工厂函数返回假值,请使用EMPTY作为Observable。最后但同样重要的是,工厂函数调用期间的异常通过调用error传递给观察者。请参阅下面的具体示例。让我们逐步完成上面的代码。首先进入defer执行逻辑:在defer内部,直接构造一个新的Observable,传入工厂函数。在第8行调用工厂函数以生成一个包含应用程序业务逻辑的Observable对象,该对象存储在input中。最后,将应用程序的订阅者订阅到这个工厂函数返回的Observable。我们再step一下,发现程序执行流程从上图中的第5行跳到了第16行,这反映了defer函数延迟创建Observable对象的行为。所谓延迟创建,准确的说应该是延迟创建包含业务逻辑的Observable对象。接下来,回到我们的应用程序代码。这时,为defer函数返回的wrapperObservable对象调用subscribe。此时会触发包含业务逻辑的Observable对象的创建:这里执行defer返回的wrapperObservable的订阅函数:调用工厂方法创建包含业务逻辑的Observable对象:当前随机数执行结果大于0.5,返回fromEvent生成的新Observable对象。紧接着,只要鼠标点击屏幕,第24行的匿名函数x=>console.log(x)就会被触发。这个匿名函数最初订阅了defer函数返回的包装器Observable对象。当工厂函数返回一个新的Observable对象时,它会自动订阅这个新的Observable对象。总结一下defer的工作原理:(1)调用defer函数时,传入一个工厂函数作为入参。这个工厂函数返回一个包含业务逻辑的新Observable对象。(2)defer函数返回另一个新的Observable对象。这个Observable对象被称为包装器或虚拟Observable对象,因为它不包含任何业务逻辑。生存的唯一价值就是实现业务逻辑Observable对象的延迟创建。(3)当订阅了wrapperObservable时,触发工厂函数的执行,生成一个新的Observable对象,同时通知它的Observer。更多Jerry原创文章在这里:《王子熙》:
