簡體   English   中英

如何在一起調用多個訂閱變量時僅調用一次函數

[英]How to call function only once when multiple subscribed variables are called together

這不是一個特別的技術問題,但我很好奇這個問題的最佳方法是什么? 雖然我在Knockout中有這個問題,但我確信用例在其他地方也是有效的。

假設我已經訂閱了2個變量simpleObserve1simpleObserve2這樣每次它們的值發生變化時,它們都會調用一個函數resetAllValues()

var simpleObserve1 = ko.observable(0), // initial values
    simpleObserve2 = ko.observable(0); // initial values

var resetAllValues = function resetAllValues() {
    /* this function takes all observable values and resets them */
    {...}
}

simpleObserve1.subscribe(function(){
    resetAllValues();
});

simpleObserve2.subscribe(function(){
    resetAllValues();
});

simpleObserve1(5); // value changed anywhere in code
simpleObserve2(10); // value changed anywhere in code

這里有2個問題。

  1. 調用resetAllValues()時,它會將所有訂閱的值更改為0,包括simpleObserve1simpleObserve2 這又反過來調用resetAllValues() 如何防止這種情況進入無限循環?
  2. 如果我想一起更新兩個變量,但只調用一次resetAllValues()怎么辦?

我試圖使用knockout的dispose()方法幫助我,但我想知道是否有更好的方法來做到這一點。

延期更新可能會幫助您。 通過在計算中使用observables的值,knockout創建訂閱。 通過擴展這個計算,快速成功的變化被組合在某種微任務中。

它們可以防止循環行為,但仍然不清楚觸發了多少更新。 即:當設置為510產生12個計算更新。 所以我不完全確定這是否能回答你的問題。

 var i = 0, simpleObserve1 = ko.observable(0), // initial values simpleObserve2 = ko.observable(0); // initial values ko.computed(function resetAllValues() { console.log("Set " + ++i + ", before:"); console.log("1: ", simpleObserve1()); console.log("2: ", simpleObserve2()); simpleObserve1(0); simpleObserve2(0); console.log("Set " + i + ", after:"); console.log("1: ", simpleObserve1()); console.log("2: ", simpleObserve2()); }).extend({ deferred: true }); simpleObserve1(5); // value changed anywhere in code simpleObserve2(10); // value changed anywhere in code 
 .as-console-wrapper { min-height: 100%; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 

我創建了一個更高階函數acceptXParams ,它將檢查params的數量是否等於fn.length或任意數字。 如果不是,則不會調用原始函數:

 function acceptXParams(fn, numOfParams) { var numOfParams = numOfParams === undefined ? fn.length : numOfParams; return function() { if(arguments.length !== numOfParams) { return; } return fn.apply(fn, arguments); } } /** example **/ function sum(a, b, c) { return a + b + c; } var sum3 = acceptXParams(sum); console.log(sum3(1, 2, 3)); console.log(sum3(1, 2)); console.log(sum3(1, 2, 3, 4)); 

更時尚的ES6版本acceptXParams

const acceptXParams = (fn, numOfParams = fn.length) => 
    (...args) => 
        args.length === numOfParams ? fn(...args) : undefined;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM