与其他控制器的回调共享来自 promise 的数据

Share data from promise with callback of other controller

控制器A通过promise发送请求。在另一个控制器 B 中同时使用 运行 回调函数的最佳方法是什么?在原始回调中通过服务广播并在另一个控制器中收听它。是否有可能将 promise 传递给控制器​​ B?

选项 1:

// controller A
service.doAjax().then( function( data ) { 
// controller A callback 
// should I broadcast "data" and listen for the event in controller B ?
} );

// controller B
$rootScope.$on();
// ... listen for the event sent from controller A to get "data

选项 2:

// controller A
var promise = service.doAjax(); 
shareService.sharePromise( promise ); // Sharing the promise with broadcast

// controller B
// get promise from shareService via $on()
promise.then( function( data) {} );

方案2的问题是回调函数会被执行多次。我不想共享数据,而是执行回调。

您可以共享承诺而不是共享数据。为您服务:

var cached = null; // assumes the ajax doesn't return a falsey value
function doAjax(){
    if(!cached) cached = $http.get(...); // actual request
    return cached;
}

这样,当两个控制器调用它时,它们将收到相同的请求 - 并且它实际上会由先调用它的人触发。通过缓存承诺(而不是数据),您还可以防止 class 有趣的竞争条件。

如果你不想总是缓存结果,你可以有一个特殊的方法来 "who you want to wait for" 实现一种屏障或会合模式:

var awaiters = {};
function randevouz(who){
    return new $q(function(resolve, reject){
         awaiters[who] = (awaiters[who] || []).concat(resolve); // add new
    });
}
function arrived(who){
    (awaiters[who] || []).forEach(function(x){ x(); });
}

让您在控制器 B 中调用:

randevouz("B").then(function(){
    // a let me know they're ready   
});

在 A 中:

doAjax().then(function(){
    arrived("A");
});