3

我拼命地寻找这个问题的答案,并以艰难的方式得出了这个答案。希望其他人能够挽救我所遭受的失去的时间。也许有人会用改进或更好的模式来回答。

编辑: 我在这里输入的一组较早的代码已被替换。

在此方法中,您可以看到如何在没有回调嵌套的情况下对异步操作进行多次调用。它还展示了如何将异步代码放入较小的可调用函数中。该方法还可以调用多个级别的异步函数。在每个级别,可以将多个异步操作串在一起以满足其意图。错误可以向上传递,并且可以通过.thens 序列冒泡。

日志输出应该有助于理解真正发生了什么。

作为解析和 JS 初学者,有两件事对我有帮助:1) 解析 JS 操作在返回 Promise 时似乎是异步的,否则,一个例外是 query.get()。2) 非常小心 .then 调用的语法。3) .then 错误函数不会捕获抛出的错误。要导致错误,请使用“return Parse.Promise.error()”。4) 要理解承诺,请观看 Mike Taulty 的截屏视频,很容易用谷歌搜索,谢谢 Mike。

此代码已在 Parse.com 上进行了测试。

function test0()
{
    console.log("test0.entry");
    var promise0 = test1("T", "col", "test1call1");

    var promise1 = promise0.then(function(ex) {
        console.log("test0.0.success - " + ex);
        return test1("T", "emailAddress", "test1call2");
    });
    var promise2 = promise1.then(function(ex) {
        console.log("test0.1.success - " + ex);
        return test2(1);
    });
    promise2.then(function(msg) {
        console.log("test0.2.success - " + msg);
        return;
    }, function(error) {
        console.log("test0.2.error " + error.message);
        return;
    });
    console.log("test0.exit");
}

function test1(clss, col, val) 
// use as a method on a save request
// returns true if the column value already exists
{
    console.log("[" + val + "]" + "test1.entry");
    var c = Parse.Object.extend(clss);
    var query = new Parse.Query(c);

    query.equalTo(col, val);
    var promise1 = query.count();
    var promise2 = promise1.then(function(count) {
        console.log("[" + val + "]" + "test1.sub.success - " + count);
        if (col == "reject") {    
            var err = new Parse.Error(10001, "new test error");
            console.log("[" + val + "]" + "test1.sub.success - return test error");
            return Parse.Promise.error(new Parse.Error(10001, "test error (10001)"));
        } 
        return(count>0);
    }, function(error) {
        console.log("[" + val + "]" + "test1.sub.error " + error.get("message"));
        return(false);
    });
    console.log("[" + val + "]" + "test1.return");
    return promise2;
};

function test2(n) 
// use as a method on a save request
// returns true if the column value already exists
{
    console.log("test2.entry");
    var c = Parse.Object.extend("T");
    var query = new Parse.Query(c);

    query.equalTo("col", "val");
    var promise1 = query.count();
    var promise2 = promise1.then(function(count) {
        console.log("test2.promise1.success - " + count);
        if (n==1) {
            return test1("T", "reject", "test2call1e");
        } else {
            return test1("T", "col", "test2call1");
        }
    });

    var promise3 = promise2.then(function(count) {
        console.log("test2.promise1.success - " + count);
        if (n==2) {
            return test1("T", "reject", "test2call2e");
        } else {
            return test1("T", "col", "test2call2");
        }
    });

    var promise4 = promise3.then(function() {
        console.log("test2.promise3.success - " + count);
        return "test2 completed";
    }, function(error) {
        // Catch some errors here and repair them
        console.log("test2.promise3.error - " + error.message);
        return Parse.Promise.as("test2 completed - error repaired");
    });

    console.log("test2.exit");
    return promise4;
};

它产生了这个输出。

I2013-03-30T01:58:19.983Z] test0.entry
I2013-03-30T01:58:19.983Z] [test1call1]test1.entry
I2013-03-30T01:58:19.984Z] [test1call1]test1.return
I2013-03-30T01:58:19.984Z] test0.exit
I2013-03-30T01:58:20.085Z] [test1call1]test1.sub.success - 0
I2013-03-30T01:58:20.085Z] test0.0.success - false
I2013-03-30T01:58:20.085Z] [test1call2]test1.entry
I2013-03-30T01:58:20.085Z] [test1call2]test1.return
I2013-03-30T01:58:20.186Z] [test1call2]test1.sub.success - 0
I2013-03-30T01:58:20.186Z] test0.1.success - false
I2013-03-30T01:58:20.186Z] test2.entry
I2013-03-30T01:58:20.187Z] test2.exit
I2013-03-30T01:58:20.338Z] test2.promise1.success - 0
I2013-03-30T01:58:20.338Z] [test2call1e]test1.entry
I2013-03-30T01:58:20.338Z] [test2call1e]test1.return
I2013-03-30T01:58:20.439Z] [test2call1e]test1.sub.success - 0
I2013-03-30T01:58:20.439Z] [test2call1e]test1.sub.success - return test error
I2013-03-30T01:58:20.439Z] test2.promise3.error - test error (10001)
I2013-03-30T01:58:20.439Z] test0.2.success - test2 completed - error repaired
4

1 回答 1

1

如果将许多内联函数链接在一起,在 Parse 上使用 Promises 会变得更加困难。相反,我所做的是将每个动作定义为一个函数,然后将它们链接在一起,并用最后一个块用 and 完成handleSuccess它们handleError。这样,每个函数都是独立的并且易于理解,而链式序列是有组织的并且易于更新。

fetchThing和函数都updateThing返回一个包含thing实例的 Promise。获取的值被传递给更新函数,然后被传递给链式序列中的下一个函数。

var fetchThing = function(objectId) {
    // set up a query with objectId
    return query.find();
};

var updateThing = function(thing) {
    // set properties on thing
    return thing.save();
}

var handleSuccess = function(result) {
    response.success(result);
};

var handleError = function(error) {
    response.error(error);
};

var objectId = 'asdfad';

fetchThing(objectId).then(function(thing) {
    return updateThing(thing);
}).then(handleSuccess, handleError);

我创建了一个完整的示例,我在 GitHub 上分享了该示例,它使用这种编程风格与 Cloud Code 和 Promises。

https://github.com/brennanMKE/PostThings/blob/master/Parse/PostThings/cloud/main.js

于 2013-12-15T07:14:04.343 回答