嵌套的WLJSONStore调用未在预期的序列中执行而不向集合添加项目

时间:2014-05-12 07:45:33

标签: ibm-mobilefirst jsonstore

这是带有dojo的Worklight 6.1代码,使用Chrome和std dev服务器Liberty进行测试。我希望这段代码要做的是查询一个集合,该集合应该有0或1个条目,如果存在,则检索一个条目,或者创建一个带有一组提供的值的条目。我要做的是存储服务的URL,ID和密码。如果这是应用程序在安装后第一次运行,我想提示用户输入此信息并存储它。稍后将添加提示用户的代码。如果它不是应用程序的第一次运行,则应将值存储在集合中并进行检索。我稍后会添加代码以允许用户更改和更新值。

现在发生的事情是.add似乎永远不会被执行,而且我通过我设置的断点看到的执行顺序似乎很奇怪。

以下是设置代码

        // set up the jsonStore
        var collectionName = 'servers';
        var collections = {};
        collections[collectionName] = {};

        // initialize the default jsonStore Monitor credentials
        var jsonURL = 'http://myserver.com:9082';
        var jsonUser = 'keyser';
        var jsonPassword = 'soze';

这是问题代码

        // Initialize the JSONStore 
        WL.JSONStore.init(collections)
            .then(function() {
                console.log("store initialized");
                // query the store
                var query = {_id: 0};
                WL.JSONStore.get(collectionName)
                .find(query)
                .then(function(arrayResults) {
                    console.log("credentials retrieved " + arrayResults.length);
                    if (arrayResults.length > 0) {
                        // retrieve the credentials from the json object
                        console.log("password retrieved " + arrayResults[0].json.password);
                        jsonURL = arrayResults[0].json.url;
                        jsonUser = arrayResults[0].json.user;
                        jsonPassword = arrayResults[0].json.password;                           
                    } else {
                        // load the default credentials into jsonStore
                        var credentials = {url: jsonURL, user: jsonUser, password: jsonPassword};
                        WL.JSONStore.get(collectionName) 
                            .add(credentials)
                            .then(function() {
                                console.log("credentials loaded " + credentials.url);
                            })
                            .fail(function(errorObject) {
                                console.log("credential load failed");
                            });                         
                    }  // end of else
                    //  Query the model list
                    queryModels();
                })  // end of get(collectionName) then

                .fail(function(errorObject) {
                    console.log("credentials not retrived");
                });  // end of get(collectionName) fail
            }) // end of init(collections) then

            .fail(function(errorObject) {
                console.log("store init failed" + errorObject);
            }); // end of init(collections) fail

    });  // end of ready

当我一步一步地按顺序流动。

的init(集合)

然后它立即跳到“准备就绪结束”。看起来很奇怪,但我是菜鸟,所以也许可以吗?

返回get(collectionName)

到.then并记录“检索到的凭据”,数组长度为0

声明的else子句

它在else子句中的get(collectionName)上中断。到目前为止一切顺利

从这里跳转到queryModels(),跳过.add(据我所知)

然后它返回到第二个get下的.then并记录“凭据已加载”

此时执行“正常”结束,除了, 该项永远不会添加到集合中,并且 queryModels在我预期之前运行,我希望它在添加项目后运行。

到目前为止,我可能很明显我是一名新秀,所以我可能会犯新秀的错误。我知道 我正在使用.then和.fails处理延迟,我正在嵌套它们,这似乎是 一种公认的技术,但我没有得到我想要的执行顺序。

我已经尝试过这段代码,用几种格式来评论第二个get(集合),并且两种方式都是barfs。

                        // WL.JSONStore.get(collectionName) 
                            .add(credentials)

                        // WL.JSONStore.get(collectionName) 
                            servers.add(credentials)

任何帮助非常感谢。谢谢!

以下是我根据以下其他答案所学到的“答案”。

Bluewing和cnandrue的答案都非常有用,我让它发挥作用。我原来遇到的主要问题是。

  1. 我没有意识到集合中的插槽0等于1的文档_id键。我试图查询_id = 0,并且从未得到命中。该系列的添加一直在使用,我只是没有正确阅读。

  2. 将queryModels移动到if / else子句(bluewing的建议)工作,并阅读引用的材料cnandreu(非常值得阅读)解释了它的工作原理。谢谢!

  3. 关于“怪异”执行序列作为断点的工件的提示也非常有用,我不再追逐那个红鲱鱼。

  4. 修复这些问题后,这是代码的工作草案。我还没有实现所有的建议,但可能会因为我对此进行了改进。再次感谢。

            // Initialize the JSONStore - you have to .init to start the collection before you can read it.
            WL.JSONStore.init(collections)
                .then(function() {
                    console.log("store initialized");
                    // query the store
                    var query = {_id: 1};
                    WL.JSONStore.get(collectionName)    // get 1
                    .find(query)
                    .then(function(arrayResults) {
                        console.log("credentials retrieved " + arrayResults.length);
                        if (arrayResults.length > 0) {
                            // retrieve the credentials from the json object
                            console.log("password retrieved " + arrayResults[0].json.password);
                            jsonURL = arrayResults[0].json.url;
                            jsonUser = arrayResults[0].json.user;
                            jsonPassword = arrayResults[0].json.password;
                            queryModels();
                        } else {
                            // load the default credentials into jsonStore
                            var credentials = {url: jsonURL, user: jsonUser, password: jsonPassword};
                            WL.JSONStore.get(collectionName)  // get 2
                                .add(credentials)
                                    .then(function(numberOfDocumentsAdded) {
                                        console.log("Number of Docs Added" + numberOfDocumentsAdded);
                                        queryModels();
                                    });  // end of .add then
                        }  // end of else
                    });  // end of get(collectionName) 1 then
                }) // end of init(collections) then
    
                .fail(function(errorObject) {
                    console.log("something failed" + errorObject);
                }); // end of init(collections) fail
    

2 个答案:

答案 0 :(得分:1)

所有JSON存储调用(如add,init等)都是异步的。因此,当您使用断点检查时,只有您获得了奇怪的流程。

为了获得执行顺序,请在加载凭据后尝试移动queryModels();

WL.JSONStore.get(collectionName) 
                        .add(credentials)
                        .then(function() {
                            console.log("credentials loaded " + credentials.url);
                            queryModels();
                        })

答案 1 :(得分:0)

我的建议与Bluewings'相同,但我想分享一些伪代码:

function handleCredentials (arrayResults, callback) {

    if (arrayResults.length > 0) {
        //.... synchronous code here.

        setTimeout(function () {
          callback();
        }, 0);

    } else {

        WL.JSONStore.get(collectionName) 
        .add({url: jsonURL, user: jsonUser, password: jsonPassword})
        .then(function() {
            callback();
        });                  
    }
}

WL.JSONStore.init(collections)
.then(function() {

  WL.JSONStore.get(collectionName)

  .find({_id: 1})

  .then(function (arrayResults) {

    handleCredentials(arrayResults, function () {
      queryModels();
    });

  });

});

注意我为handleCredentials创建了一个函数,该函数将执行同步操作(使用find调用的结果设置一些变量)或异步操作(调用add添加凭据)。调用带有0的setTimeout以保留异步行为,详细解释herehandleCredentials函数完成后,通过回调模式调用queryModels函数。

顺便说一句,我建议阅读这篇博文:What’s so great about JavaScript Promises?。特别是"错误处理"部分。您不需要为每个承诺添加.fail,您可以使用较少的失败函数来逃避,并且错误对象应该提供有关错误的详细信息。记录JSONStore错误对象here,注意它们包含失败的来源(例如src: 'find')。