2017-09-19 10 views
0

コールバック内で渡される変数を変更または更新するにはどうすればよいですか?コールバックで渡される変数を変更する

例:

function App() { 
 
    this.components = {}; 
 
    this.queue = {}; 
 
} 
 

 
App.prototype.import = function (name, cb) { 
 

 
    if (this.components[name]) { 
 
    return cb(this.components[name]); 
 
    } 
 

 
    if (!this.queue[name]) { 
 
    this.queue[name] = []; 
 
    } 
 

 
    // push to queue 
 
    this.queue[name].push(cb); 
 

 
}; 
 

 
App.prototype.export = function (name, data) { 
 
    
 
    let that = this; 
 

 
    // set components instance 
 
    this.components[name] = data; 
 

 
    // call queue ? 
 
    if (this.queue[name]) { 
 

 
    // call each import request 
 
    this.queue[name].forEach(function (cb) { 
 
     cb(that.components[name]); 
 
    }); 
 

 
    // clean up 
 
    delete this.queue[name]; 
 

 
    } 
 
}; 
 

 
App.prototype.reload = function (name, data) { 
 
    console.log("Reload module %s", name); 
 
    delete this.components[name]; 
 
    this.components[name] = data; 
 
}; 
 

 

 
var app = new App(); 
 

 
app.import("module1", function(data){ 
 
    console.log("Imported module1"); 
 
    setInterval(function(){ 
 
    console.log(data, app.components["module1"]); 
 
    }, 1000); 
 
}); 
 

 
setTimeout(function(){ 
 
    app.export("module1", {data: "Hello World"}) 
 
}, 1000); 
 

 
setTimeout(function(){ 
 
    app.reload("module1", {data: "Changed data"}); 
 
}, 5000);

あなたはこのsnipetを実行している場合あなたが見ることができます: app.components.module1が更新されなくコールバックスコープを。 どうすればこの問題を解決できますか?

app.components.module1にもcbの変数が更新されたければなりません。

答えて

0

参照を緩めるほど、オブジェクトを削除することはできません。しかし、あなたはそれを変異させることができます:

App.prototype.reload = function (name, data) { 
    console.log("Reload module %s", name); 
    Object.keys(this.components[name]).forEach(key =>{ 
    delete this.components[name][key]; 
    }); 
    Object.assign(this.components[name],data); 
}; 

(プリミティブ型でその文句を言わない仕事と最高のコード設計をイマイチ)

それとも、リスナーのパターンのようなSTHを実装:

class Listener { 
constructor(){ 
    this.listeners = new Map(); 
    } 
    on(event,handler){ 
    if(this.listeners.has(event)){ 
     this.listeners.get(event).push(handler); 
    }else{ 
     this.listeners.set(event,[handler]); 
    } 
    } 

    trigger(event, ...params){ 
    (this.listeners.get(event) || []).forEach(handler => handler(...params)); 
    } 
} 

ので、1缶do:

const loader = new Listener(); 
loader.on("sth",console.log); 

loader.trigger("sth",{a:1}); 
+0

これはイベントエミッタと似ています。 それは私が欲しいものではありません。リスナーを再度呼び出さずにコールバック引数オブジェクトを変更します。 – Marc

関連する問題