【问题标题】:chain async operations using native JavaScript Promise使用原生 JavaScript Promise 链式异步操作
【发布时间】:2014-12-10 06:06:15
【问题描述】:

我跟踪了两个异步操作,然后定义了最终的 onResultonFault。如何链接两个异步操作getConnection,然后select,最后调用onResultonFault

编辑需要帮助来保证以下序列。

    new Promise(this.getConnection)
        .then(this.select)
        .then(this.onResult)

getConnection: function(resolve, reject) {
    console.log('get connection')
    if(database = common.model.connections.Sync.getConnection()) {
        database.transaction(function(transaction){
            resolve(transaction);
        });
    } else {
        reject("Connection Error");
    }
},

select: function(transaction) {
    console.log('select', transaction)
    var self = this;

    var query = "SELECT * FROM configuration WHERE key = 'schedule'";
    self.transaction.executeSql(query, [], function(transaction, resultSet){self.selectTransactionComplete(transaction, resultSet)}, function(){self.selectTransactionError()});
},

selectTransactionComplete: function(transaction, resultSet) {
    console.log('select transaction complete')
    if(resultSet.rows.length == 0) {
        this.onResult(false);
    } else if(new Date().getTime() - new Date(common.Config.getLastSync()).getTime() > resultSet.rows.item(0).value) {
        this.onResult(true);
    }
},

selectTransactionError: function(error) {console.log(this.constructor.NAME, this.selectSQL); console.log(error);},

onResult: function(data) {
    console.log(data);
},

onFault: function(info) {
    console.log(info)
}

【问题讨论】:

  • 您似乎正在使用回调之类的承诺。不;而是返回它们。例如,asyncAction 应该返回一个承诺或将两个参数(两者都不能直接抛出)传递给then
  • 删除了 asyncAction,因为它超出了范围,我如何通过这两个异步操作从 getConnection 到达 onResult 调用 - getConnectionselect,就像这里 @987654322 @(排队异步操作)
  • 感谢在我的示例上下文中使用书面代码的任何帮助,我已经阅读了文章,理解了单个异步但仍然对多个排队异步操作感到困惑和困惑,我注意到 Promise.all 但不确定是否这将适用于我的情况
  • 在阅读了几件事后,请在下面的回答中查看我的尝试,这是应该的吗?

标签: javascript promise es6-promise


【解决方案1】:

在尝试了几件事之后,这是应该如何完成的吗?请检查

    this.getConnection()
        .then(this.select, this.getConnectionError)
        .then(this.selectTransactionComplete, this.selectTransactionError)

getConnection: function() {
    console.log('get connection')

    var promise = new Promise(function(resolve, reject){
        try {
            database = common.model.connections.Sync.getConnection();
            database.transaction(function(transaction){
                resolve(transaction);
            });
        } catch(error) {
            reject("Connection Error");
        }
    });

    return promise;
},

getConnectionError: function(info) {
    console.log("connectionError");
    this.onFault();
},

select: function(transaction) {
    console.log('select')
    var self = this;

    var promise = new Promise(function(resolve, reject){
        var query = "SELECT * FROM configuration WHERE key = 'schedule'";
        transaction.executeSql(query, [], function(transaction, resultSet){resolve(resultSet)}, function(error){reject(error)});
    });

    return promise;
},

selectTransactionComplete: function(resultSet) {
    console.log('selectTransactionComplete')

    /*if(resultSet.rows.length == 0) {
        this.onResult(false);
    } else if(new Date().getTime() - new Date(common.Config.getLastSync()).getTime() > resultSet.rows.item(0).value) {
        this.onResult(true);
    }*/
},

selectTransactionError: function(error) {
    console.log('selectTransactionError')
    //console.log(this.constructor.NAME, this.selectSQL);
    //console.log(error);
},

onResult: function(data) {
    console.log('onResult')
},

onFault: function(info) {
    console.log('onFault')
}

【讨论】:

    【解决方案2】:

    如果您使用像 q 这样的 Promise 库,则链接 Promise 的方式如下;

    getConnection: function() {
        var deferred = Q.Defer();
        console.log('get connection')
    
            try {
                database = common.model.connections.Sync.getConnection();
                database.transaction(function(transaction){
                    deferred.resolve(transaction);
                });
            } catch(error) {
                deferred.reject("Connection Error");
            }
    
        return deferred.promise;
    }
    

    当您打电话时,您会执行以下操作;

    Q.when(getConnection)
    .then(function(result){
     // handle success or resolve
    }, function(error){
     // handle rejection.
    };
    

    另外我建议阅读common js promises specification

    【讨论】:

    • 感谢 Jerome 提供的代码,不过,我希望在原生 JavaScript 承诺中做同样的事情
    • Q.when 是多余的(只需调用 getConnection)。此外,如果您使用 Q.Promise(在 Q 的新版本中)而不是 deferreds,则无需键入 try/catch,它会为您完成。
    • 感谢 cmets 伙计们。我可以问一下,当为此实现了良好的库时,为什么要执行 vanilla JS?
    猜你喜欢
    • 2020-02-22
    • 2018-01-14
    • 2015-10-06
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    相关资源
    最近更新 更多