【问题标题】:Angularjs load resources on after the other using promiseAngularjs使用promise在另一个之后加载资源
【发布时间】:2013-04-24 18:22:29
【问题描述】:

在服务中,我想使用 $http 加载资源。加载资源后,我想将其存储在变量中。然后,我需要加载一个子资源并存储它。我知道 promise 是为这种工作而设计的,但似乎有太多如何使用它,我有点困惑。这是我的代码:

var project = {};
var todo = {};

function init(){
        var idProject = 21;
        var idTodo = 6;            

        // If idProject is specified
        if ( idProject != null ) {

            // First, load project data
            var promise = WorkspaceManager.getProject($rootScope.workspace, idProject);

            // Then save project data
            promise.then(function(response){
                project = response.data;                    
                return project;
            });

            if ( idTodo != null ) {
                //  Then load todo data
                promise.then(function(project){   
                    return ProjectManager.getTodo(project, idTodo);
                });

                // Then save todo data
                promise.then(function(response){
                    todo = response.data;                    
                    return todo;
                });
            }       
        }

        console.log(project); // returns {}
    }

init()

提前致谢!

【问题讨论】:

  • return project;return todo; 应该做什么?
  • 它使承诺序列继续进行。它在下一个then 中检索。像这样:if ( idTodo != null ) { // Then load todo data promise.then(function(project){
  • 不,结果只会在 chained 中使用 - 如果你在同一个 Promise 上放置很多回调,则不会。

标签: javascript angularjs promise


【解决方案1】:

如果我理解正确,这比乍一看要复杂。您似乎需要一个函数来链接两个异步进程并返回一个复合值的承诺,该复合值包含由第一个 第二个进程获取的数据。

至少有两种方法可用:

  • 简单但不优雅:在每个异步过程中,将所需的值累积为外部对象的属性。
  • 优雅但笨拙:从每个异步进程中,将所需的值作为对象的属性累积,并返回其承诺。

下面的代码采用第一种方式:

function init() {
    var idProject = 21;
    var idTodo = 6;
    var projectObj = {};//This object acts as a "bank" for asynchrounously acquired data.
    if ( idProject != null ) {
        return WorkspaceManager.getProject($rootScope.workspace, idProject).then(function(response) {
            projectObj.project = response.data;//put `response.data` in the bank as .project.
            if( idTodo != null ) {
                return ProjectManager.getTodo(response.data, idTodo);
            }
        }).then(function(toDo) {
            projectObj.toDo = toDo;//put `toDo` in the bank as .toDo .
            return projectObj;
        });
    }
}

init().then(function(projectObj) {
    console.log(projectObj.project);
    console.log(projectObj.toDo);
});

或者(仍然是第一种方法)带有错误处理程序:

function init() {
    var idProject = 21;
    var idTodo = 6;
    var projectObj = {};//This object acts as a "bank" for asynchrounously acquired data.
    if ( idProject != null ) {
        return WorkspaceManager.getProject($rootScope.workspace, idProject).then(function(response) {
            projectObj.project = response.data;//put `response.data` in the bank as .project.
            if( idTodo != null ) {
                return ProjectManager.getTodo(response.data, idTodo);
            }
            else {
                $q.defer().reject('idTodo invalid');
            }
        }).then(function(toDo) {
            projectObj.toDo = toDo;//put `toDo` in the bank as .toDo .
            return projectObj;
        });
    }
    else {
        return $q.defer().reject('idProject invalid');
    }
}

init().then(function(projectObj) {
    console.log(projectObj.project);
    console.log(projectObj.toDo);
}, function(errorMessage) {
    console.log(errorMessage);
});

未经测试

【讨论】:

  • 感谢您的两个答案,我试一试,让您知道哪个更适合我。
  • Frank6,这两个答案基本相同,只是在第一个版本中,为了清楚起见,我省略了错误处理。
【解决方案2】:

按照您的方式,您正在创建从第一个承诺派生的“兄弟”承诺。一旦WorkspaceManager.getProject promise 被解决,所有的 promise 都会被解决。我相信你想要的是将它们全部链接起来,这样当第一个承诺得到解决时,你会要求 Todo 数据,当你得到它时,你要求保存它。如果是这种情况,您应该从每个 Promise 中获取派生的 Promise。

// Then save project data
promise = promise.then(function(response){
  project = response.data;
  return project;
});

//  Then load todo data
promise = promise.then(function(project){   
  return ProjectManager.getTodo(project, idTodo);
});

// Then save todo data
promise.then(function(response){
  todo = response.data;                    
  return todo;
});

试着说明一下,第一种方法是这样的:

var mainPromise = ...;
mainPromise.then(function loadTodo(mainPromiseReturn){});
mainPromise.then(function saveTodo(mainPromiseReturn){});

loadTodosaveTodo 是平行的,它们没有相互链接。他们都收到相同的data

我建议的方法是:

var mainPromise = ...;
mainPromise
  .then(function loadTodo(mainPromiseReturn){})
  .then(function saveTodo(loadTodoReturn){});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 2015-02-19
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多