javascript - 使用 Pattern promise jquery 将异步函数更改为同步函数

标签 javascript jquery asynchronous

我正在尝试使用 Javascript 的最佳实践,但这对我来说太难了。在这种情况下,我想使用一些函数来“避免”回调。我正在尝试使用 jquery 的 Deferred 对象来完成它。所以我相信我不知道如何工作。

我正在使用 phonegap + emberjs + cordova-sqlite-plugin

我有以下实现回调的函数。

getPuntos: function(callback)
{
    var db = window.sqlitePlugin.openDatabase("Rondas", "1.0", "Dev", -1);

    var ret ={data:false};
    db.transaction(function(tx)
    {
        tx.executeSql("SELECT * from Punto;",[], function(tx, res)
        {
            if( res.rows.length !== 0)
            {
                var puntos =  [];
                for( var i=0; i<res.rows.length; i++)
                {
                    var descripcion = res.rows.item(i).descripcion;
                    var id = res.rows.item(i).id;
                    //console.log( descripcion );
                    var punto = App.Punto.create( { index: i, id:id, descripcion: descripcion});
                    puntos.push( punto );
                }
                ret.data = puntos;
                callback(ret.data);
            }

        });
    },function(tx,err){
        console.log('Error SQL'+err);
    },function(){
        console.log( 'Base de datos abierta' );
    });     
}

我也用这个:

this.getPuntos(function(puntos){
   for( var i=0; i<puntos.length; i++){
     console.log( puntos[i] );
   }
});

好吧,但我尝试实现一些非常清晰和简单的东西,比如:

//whitout use a callback.
var puntos = this.getPuntos();
for( var i=0; i<puntos.length; i++){
     console.log( puntos[i] );
}

然后我尝试这样做:

  1. 将函数 getPuntos 更改为 _getPuntos,此函数有一个延迟对象。
  2. getPuntos 函数是一个包装器,用于处理 _getPuntos 方法中 promise 的结果并尝试返回。(但不起作用)
_getPuntos: function()
{
    var db = window.sqlitePlugin.openDatabase("Rondas", "1.0", "Dev", -1);
    var deferred = jQuery.Deferred();   
    var ret ={data:false};
    db.transaction(function(tx)
    {
        tx.executeSql("SELECT * from Punto;",[], function(tx, res)
        {
            if( res.rows.length !== 0)
            {
                var puntos =  [];
                for( var i=0; i<res.rows.length; i++)
                {
                    var descripcion = res.rows.item(i).descripcion;
                    var id = res.rows.item(i).id;
                    //console.log( descripcion );
                    var punto = App.Punto.create( { index: i, id:id, descripcion: descripcion});
                    puntos.push( punto );
                }
                //ret.data = puntos;
                //callback(ret.data);
                deferred.resolve(puntos);
            }

        });
    },function(tx,err){
        console.log('Error SQL'+err);
    },function(){
        console.log( 'Base de datos abierta' );
    });
    return deferred.promise(); 
},

包装器:

getPuntos: function()
{
    var promise  = this._getPuntos();
    var ret = {data:false};
    promise.done(function(result)
    {
        ret.data = result;
        return ret.data;
    }); 
    while(ret.data ===false ){} //wait for the result until it's available
    return ret.data;        
},

在主函数中我调用它:

var puntos = this.getPuntos();
console.log( puntos+"--shoulbe [object]"); //I get Undefined or false, but no my array.

所以,有什么办法可以做到这一点,将异步函数转换为同步函数 功能?

感谢您的所有回答。

最佳答案

这里的主要问题是第二个示例中的 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 完成时 (promise.done),它会返回 ret.data 但这会返回到 promise 并被忽略。它在错误的范围内。你在传统的“拉”模型中思考,数据被拉向你,程序阻塞直到数据可用。 Javascript 使用回调,更像是一种“推送”模型,其中数据在可用且没有阻塞时被推送到回调。

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

getPuntos: function() 
{
    var promise  = this._getPuntos();
    return promise;
},

并且 main 函数应该在 promise 完成时添加一个回调。

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

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

关于javascript - 使用 Pattern promise jquery 将异步函数更改为同步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24985933/

相关文章:

javascript - 代码审查 : Efficient? 它会工作吗?

JavaScript EventSource 在 Apache 基本身份验证后不会打开连接

javascript - 计算字段数量并限制为 10

jquery - 如何使用标签管理器?

java - 对同一 Web 服务进行多个异步调用的最佳方法

java - 提高数据库访问性能

javascript - 如何将二进制消息传递给 JavaScript Web Worker 或从 JavaScript Web Worker 传递二进制消息?

javascript - 在用户提交表单之前,如何检查文本框和复选框是否已填写并选中?

Javascript 从 Promise 获取数据(axios)

javascript - 谷歌图表 : How I can change "Choose a value..." in controlType: CategoryFilter of ControlWrapper