DOJO构造函数同步

DOJO Constructor Synchronous

我在尝试同步 Javascript 中的 DOJO 构造函数时遇到问题。

我有一个 "class" 我需要实例化的 MYCLASS:

MYCLASS.JS

define([
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/when',
'dojo/Deferred',

], function(declare, lang, when, Deferred){

    return declare(null, {
        var1: null,
        var2: null,
        var3: [],

    constructor: function(options){
        this.var1 = options.var1;
        this.var2 = options.var2;
        this._doSomething(); 
    },

    _doSomething: function(){
        //Here the "var3" is completed.
        //Some code which needs more time with REST requests.
    }
});
});

好的,那么我需要在我的控制器中获取一个这样的实例:

var myInstance = new MYCLASS(options);

它工作正常,除了 var3,它没有被填充。 我读过 "Deferred" 或“"when",但我不知道如何应用它。

提前谢谢你, 玉米片.

好吧,使用 deferreds 不会使其同步,但它可能会解决您的问题。 deferreds 做的事情很简单,它们提供了一个 API 来获取异步数据。

例如,考虑以下场景:

var myAsyncData = null;
// ...
// The following is some asynchronous code (could be a REST call)
setTimeout(function() {
    myAsyncData = 3;
}, 1000);
// ...
console.log(myAsyncData);

这显然会记录 null 因为数据是异步填充的,而在您记录的那一刻,请求还没有完成。

为了解决这个问题,人们可以使用 deferreds,例如:

var myDeferred = new Deferred();
var myAsyncData = myDeferred.promise;
// ...
// The following is some asynchronous code (could be a REST call)
setTimeout(function() {
    myDeferred.resolve(3);
}, 1000);
// ...
myAsyncData.then(function(myData) {
    console.log(myData);
});

这里发生的是数据被包裹在某种 API 中,它实际上会打印 3.
这是有效的,因为在代码的 then() 部分,您正在等待数据。但请记住,then() 函数中的代码块本身也是异步的!


回到你的案例。如果您正在使用 dojo/request/xhr 那么您不必自己使用 dojo/Deferred,因为该模块已经在内部使用了 deferreds。

你应该写的是:

define([
    'dojo/_base/declare',
    'dojo/_base/lang',
    'dojo/request/xhr'
], function(declare, lang, xhr){

    return declare(null, {
        var1: null,
        var2: null,
        var3: null,

        constructor: function(options){
            this.var1 = options.var1;
            this.var2 = options.var2;
            this._doSomething(); 
        },

        _doSomething: function() {
            //Here the "var3" is completed.
            //Some code which needs more time with REST requests.
            this.var3 = xhr("rest/request", {
                handleAs: "json"
            });
        }
    });
});

那么在你的代码中你应该使用:

var myInstance = new MYCLASS(options);
myInstance.var3.then(function(var3Data) {
    console.log(var3Data); // This contains the actual value!
});

如果您在获得 REST 服务的响应时需要做一些额外的处理,那么您可以使用 deferreds,例如:

_doSomething: function() {
    //Here the "var3" is completed.
    //Some code which needs more time with REST requests.
    var dfd = new Deferred();
    this.var3 = dfd.promise;

    xhr("rest/request", {
        handleAs: "json"
    }).then(function(myData) {
        dfd.resolve(myData.someProperty);
    });
}

但请记住,使用 deferreds 总是涉及三个步骤。首先你必须创建延迟,然后你必须解析它,要听解析数据,你应该使用 then() 函数。