Javascript 异步加载模块属性

Javascript 异步加载模块属性,javascript,requirejs,amd,ractivejs,Javascript,Requirejs,Amd,Ractivejs,我定义了一个模块(module1),它应该异步加载属性的值。如何在定义此属性后立即在应用程序中使用此属性 我的设置(简化) v1 app.js require(['module1'], function(mod) { mod.loadPerson(function(person) { document.getElementById("greeting").value = person.getPersonName(); }); }); define(['jquer

我定义了一个模块(module1),它应该异步加载属性的值。如何在定义此属性后立即在应用程序中使用此属性

我的设置(简化) v1 app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
values/person.json

这仅在GET几乎是瞬间发生时有效,否则它会失败,因为调用getPersonName时_person未定义

v2 为了解决这个问题,我想我应该注册一个回调函数,在用户被加载时通知应用程序

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
如果GET很慢,但如果GET很快,则可以使用此方法。调用
.done()
时,onload是未定义的

在app.js中定义_person值后,是否有一种很好的方法可以在定义后立即使用这些值

我使用的是RequireJS,但我的问题通常适用于AMD

编辑 为了简化我的示例,我删除了一个可能很重要的层。我正在为UI使用RactiveJS

设置(稍微简化) app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
编辑2 我当前的解决方案可能会有所改变。注册一个回调,在加载人员时通知app.js。若注册回调时已加载人员,则立即调用回调

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}

我就是这样做的。基本上,它与V2没有太大区别,但它增加了更多的嵌入

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}

您也可以使用承诺而不是简单的回调。

承诺在这里是一个很好的选择,因为回调总是异步调用的-您永远不会遇到在设计之前调用
\u onload()
的混乱情况

不幸的是,jQuery的promise实现没有遵守,因此您无法得到保证。如果可能的话,您可以使用一个替代的AJAX库,比如

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
define(['module1'],函数(mod){
模块then(功能(人员){
//用person.name做某事
}
});
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
define(['reqwest'],函数(reqwest){
返回reqwest('values/person.json');
});
使用文本加载器插件 另一个选择是,因为您已经在使用AMD,所以可以使用加载程序插件,例如:

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
define(['module1'],函数(person){
//用person.name做某事
});
module1.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
define(['text!values/person.json'],函数(personJSON){
返回JSON.parse(personJSON);
});
使用文本加载器插件 事实上,甚至还有一个,所以在这个示例中,您可以完全取消module1:

app.js

require(['module1'], function(mod) {
    mod.loadPerson(function(person) {
        document.getElementById("greeting").value = person.getPersonName();
    });
});
define(['jquery'], function($) {
    return {
        loadPerson : function(callback) {
            $.get('values/person.json').done(function(data) {
                  _person = data;

                 callback({
                    getPersonName: function() { return _person.name; }
                 });
            });

        }
    }
}
define(['json!values/person'],函数(person){
//用person.name做某事
});

谢谢。当我输入我的问题时,我有一个类似的想法。为了简化我的示例,我删除了一个层,因为我在UI中使用了ractive。你会在我的编辑中使用
app.js
并在回调中设置ractive吗?@Enrico是的,我会。V1不是一个选项,我想,除非你使用的是同步ajax。Rich,tha谢谢Ractive!我加载的值实际上来自chrome.storage api,因此文本加载器插件对我来说不起作用;我认为ajax示例将更广泛地适用和理解。很抱歉头部是假的。我选择注册回调,并在回调时定义值时立即调用回调ACK正在注册,请参阅上面的第二次编辑。啊,我明白了,不用担心。这对于Chrime.Stor是不好的。对于回调是否同步或异步发生,这是不一致的。Isaac Schlueter写了一篇关于……我认为我必须预先警告我是否需要使用它。欢迎您,很高兴您发现它有用。