2

我最近开始研究 AS3 中的自定义类(以磨练我的最佳实践编码习惯),并希望创建一个数据库类,允许用户首先实例化一个包含类中方法添加所需的所有信息的类,删除、修改(等)MySQL 表中的行(通过 PHP)。当然,这涉及到使用 URLRequest、URLLoader 等。我的问题是,是否有人想出了一种方法,如何从专门包含该 var 数据的方法中返回数据,而不依赖于本质上调度事件的方法(然后必须创建一个侦听器,而不是将其内置到类中)。例如,

var myDB:dataBase = new dataBase("dbase","table","username","pword");

//this creates an instance of a database class with methods like:

trace(myDB.fetch(1)); //gets first row of table as a delimited string

或者

if (myDB.delete(1)) {} 
//returns Boolean true if delete of row 1 was successful

我发现下面的答案包含一种创建返回事件的类的方法:

在 Actionscript 3.0 中结合 URLRequest、URLLoader 和完整的事件侦听器?

但我希望该方法返回包含来自数据库的数据或布尔确认的字符串,而不是调度事件侦听器。这是我制作的课程的示例:

package com.customClasses {
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLVariables;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequestMethod;
    import fl.events.DataChangeEvent;
    import flash.events.Event

    public class dataBase {
        public var dbs:String = "";
        public var usr:String = "";
        public var pwd:String = "";
        public var tab:String = "";
        var returnData:String = "";

    // Constructor
    public function dataBase(dbs:String, usr:String, pwd:String, tab:String) {
        this.dbs = dbs;
        this.usr = usr;
        this.pwd = pwd;
        this.tab = tab;
    }

    public function fetch(idn:uint, par:String):String { 
        var returnData:String = "blank";
        var vUrlReq:URLRequest = new URLRequest ("dBase.php");
        var vUrlVars:URLVariables = new URLVariables(); 

        function onLoadVarsComplete(event:Event): void {
            //retrieve success variable from our PHP script:
            if(event.target.data.msg == "success") {
                var rawData:URLVariables = new URLVariables( event.target.data );
                returnData = rawData.fromPHP;
            } else {
                returnData = "failed!";
            }
        }
        vUrlReq.method = URLRequestMethod.POST;    
        vUrlVars.dir=dbs; // name of table affected
        vUrlVars.alpha=usr; // username
        vUrlVars.beta=pwd;  // password
        vUrlVars.dbase=tab; // name of table affected
        vUrlVars.func="fetch"; // function for php script to use
        vUrlVars.idnum=idn; //if >0 search for record with that id
        vUrlReq.data = vUrlVars;
        var vLoader:URLLoader = new URLLoader (vUrlReq);
        vLoader.addEventListener("complete", onLoadVarsComplete);
        vLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
        vLoader.load(vUrlReq);

        return (returnData);
    }

returnData 返回“空白”......所以我意识到我的方法没有按预期工作。我还意识到 returnData 字符串存在一些范围问题,并且我正在使用嵌套函数(可能是禁止的)。否则,有什么想法吗?

4

2 回答 2

1

As you've stated it, this can't be done in AS3. You cannot wait for an asynchronous operation (such as URLLoader/load()) before returning the function and continuing script execution.

What you can do, if you'd prefer not to use addEventListener() so much, is pass through callbacks, or implement method chaining of promises. These patterns are not necessarily better than using events, and have their own problems, but let you write code that is arguably more readable as a sequence. These patterns are common in Javascript (which has the same asynchronous behavior as ActionScript), for example jQuery. Beware of "callback hell" and "train wrecks". These techniques aim to make things simpler to write but sometimes make things more error prone.

于 2015-02-16T02:22:10.577 回答
1

做你想做的事,你可以使用回调函数或DataEvent监听器,像这样:

DB.as:

package  {

    import flash.net.*;
    import flash.events.*;

    public class DB extends EventDispatcher {       

        public static const DATA_LOADED = 'data_loaded';

        public function DB() {
        }

        public function getDataUsingDataEvent(file_path:String):void {

            var url_loader:URLLoader = new URLLoader();
                url_loader.addEventListener(
                    Event.COMPLETE, 
                    function(e:Event):void
                    {
                        var event:DataEvent = new DataEvent(DATA_LOADED, true, false, url_loader.data);
                        dispatchEvent(event);
                    }
                )
                url_loader.load(new URLRequest(file_path));     
        }

        public function getDataUsingCallback(file_path:String, callback:Function):void {

            var url_loader:URLLoader = new URLLoader();
                url_loader.addEventListener(
                    Event.COMPLETE, 
                    function(e:Event):void 
                    {
                        callback(url_loader.data);
                    }
                )
                url_loader.load(new URLRequest(file_path));     
        }

    }

}

接着 :

var db:DB = new DB();

    db.addEventListener(
        DB.DATA_LOADED, 
        function(event:DataEvent):void {
            trace(event.data);
        }
    )   
    db.getDataUsingDataEvent('file_path');

    db.getDataUsingCallback(
        'file_path', 
        function(data:String):void {
            trace(data);
        }
    )

希望能有所帮助。

于 2015-02-16T02:02:13.403 回答