Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用模式promise jquery将异步函数更改为同步函数_Javascript_Jquery_Asynchronous - Fatal编程技术网

Javascript 使用模式promise jquery将异步函数更改为同步函数

Javascript 使用模式promise jquery将异步函数更改为同步函数,javascript,jquery,asynchronous,Javascript,Jquery,Asynchronous,我试图使用Javascript的最佳实践,但这对我来说太难了。在这种情况下,我想使用一些函数“避免”回调。我正试图使用jquery的延迟对象来实现这一点。所以我相信我不知道如何才能很好地工作 我正在使用phonegap+emberjs+cordova-sqlite插件 我有一个实现回调的函数 getPuntos:function(回调) { var db=window.sqlitePlugin.openDatabase(“Rondas”、“1.0”、“Dev”、-1); var ret={dat

我试图使用Javascript的最佳实践,但这对我来说太难了。在这种情况下,我想使用一些函数“避免”回调。我正试图使用jquery的延迟对象来实现这一点。所以我相信我不知道如何才能很好地工作

我正在使用phonegap+emberjs+cordova-sqlite插件

我有一个实现回调的函数

getPuntos:function(回调)
{
var db=window.sqlitePlugin.openDatabase(“Rondas”、“1.0”、“Dev”、-1);
var ret={data:false};
数据库事务(功能(tx)
{
tx.executeSql(“从Punto中选择*”,[],函数(tx,res)
{
如果(res.rows.length!==0)
{
var puntos=[];

对于(var i=0;i,这里的主要问题是,第二个示例中的getPuntos()函数不返回任何内容,因此返回null/false值

getPuntos: function() 
{
    var promise  = this._getPuntos();
    var ret = {data:false};
    promise.done(function(result)
    {
         // This happens in the future
         ret.data = result;
         return ret.data;
    });    
// This happens now and there is nothing returned 
},
当你的承诺完成时(promise.done)它返回ret.data,但这返回到承诺中并被忽略。它在错误的范围内。您在传统的“拉”模型中思考,在该模型中,数据被拉向您,程序阻塞,直到数据可用。Javascript使用回调,更像是“推”模型,当数据可用且存在时,数据被推到回调上禁止阻塞

你需要重新安排事情。例如,getPuntos函数应该返回承诺

getPuntos: function() 
{
    var promise  = this._getPuntos();
    return promise;
},
主函数应该在承诺实现时添加回调

var puntos = this.getPuntos();
puntos.done(function(result) {
    console.log( result+"--shoulbe [object]");
});

虽然getPuntos()函数在这里有点多余,因为它只是返回_getPuntos()的值。

但问题是,
getPuntos()函数设置了
promise.done
操作,但是返回的值永远不会传递给程序的其余部分。正如NoxHarmonium所说的,
getPuntos()
方法是多余的,应该与
\u getPuntos()
结合使用,但您可能需要以下内容(如中所示)

PuntosPromise = function() {
    this.result = null;
    this._getPuntos = function() {
        var deferred = $.Deferred();
        setTimeout(function(scope) {
            scope.result = "It works."
            deferred.resolve();
        }, 500, this);
        return deferred.promise();
    }
    this.getPuntos = function()
    {
        var promise  = this._getPuntos();
        return promise;        
    }
    this.getResults = function() {
        return this.result;
    };
}
$("#tester").click(function() {
    var test = new PuntosPromise();
    $.when(test.getPuntos()).then(function() {
        alert(test.getResults());
    });
});
编辑:


请参阅下面给出的@Bergi的修改。虽然这段代码有效,但他的解决方案更简洁。

否。承诺不会神奇地使函数同步(这会破坏并发点)。它们只是一个好的名称。a)不要将名称
承诺
用于任何不是承诺构造函数的内容(你的是一个自定义puntos getter无论如何)b)不要使用
结果
变量-只需解决延迟问题!@Bergi感谢你的建议。至于(a),我在实际代码中永远不会这样做;我只是写得又快又草率。至于(b),你能解释一下为什么我写的东西是不好的实践吗?我个人喜欢它提供的额外抽象,但这主要是出于审美:我觉得这更具可读性。这是不好的实践,因为延迟本身能够存储结果。承诺确实代表未来(结果)值,而不是任务的完成。请不要告诉我可读性较差。@Bergi感谢您简洁明了地回答我的问题。感谢您的回答,但函数
getPuntos
的目的是返回单个结果,而不是回调,如果我能做
var test=new puntosmission()
然后不加任何内容
var r=test.getResults()。