angular js结合了异步和同步代码

时间:2015-07-05 08:37:41

标签: javascript angularjs promise angularjs-service angular-promise

我正在使用角度resource modul来处理我的restfull网络服务器。例如,我有一个方法,它返回一个包含10个元素的数组,我想要做的只是将结果保存到一个名为books的javascript变量(不在角度范围中)。

所以我写了一个简单的方法,如下所示:

function getBooks(user_id) {
    var books = [];
    BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
    });
    return books;
}

让我们假设 BookFactory.getBooks.query 按预期工作,并真正返回10个元素。 所以这个函数里面有一个简单的逻辑,我只是​​将每个元素推送到数组 books

我还有一个用于测试getBooks()功能的测试功能。这是:

$scope.testGetBooksMethod = function (user_id) {
    var resut = getBooks(user_id);
    alert(resut.length);
};

警报中的结果将始终为0.我知道这部分代码:

BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
            angular.forEach(result, function(i) {
                books.push(i);
            });
        });

异步工作,直到处理服务器请求,函数getBooks()返回一个空的书籍数组(如果我错了,请纠正我)。

这是一个问题,我如何编辑我的功能,正确地工作。我想从休息中获取数据,用这些数据填充数组books,然后返回它。

提前致谢。

2 个答案:

答案 0 :(得分:2)

  

我想从休息中获取数据,用这些数据填充数组书籍,然后将其返回。

这就是事情。异步编程与同步不兼容。所以你不能把它们组合起来。但是,你可以使用类似同步的方式工作,这就是promises非常强大的地方。您不会返回//ALL IS WORKING JUST FINE //ALL VALUES; POSTS; CF'S ARE VISIBLE IN THE WP BACKEND!!! //BUT CRED DOES NOT "READ" THE CF VALUES WHICH COME FROM BY BELOW wpdb QUERY, (see line 94 to 105 ) function create_exams_save_data_action( $post_id, $form_data ) { // the "generate exam form" if ( $form_data['id'] == 1081 ) { global $wpdb; //get the curretn question post $post = get_post($post_id); //get current question's parent exam //get the current question's parent (mother-exam) post and ID stuff $parent_exam_id = get_post_meta($post_id, '_wpcf_belongs_exam_id', true); $parent_exam_post = get_post($belongs_to_parent_exam); $parent_exam_name = $parent_exam_post->post_name; //get the mother-exam's parent (training) $exam_belongs_to_training = get_post_meta($parent_exam_id, '_wpcf_belongs_training_id', true); //current user, new author global $current_user; get_currentuserinfo(); $new_exam_title = $current_user->user_login; $new_exam_owner = $current_user->ID; //insert the new exam, with parent the Training $new_exam = array( 'comment_status' => $parent_exam_post->comment_status, 'ping_status' => $parent_exam_post->ping_status, 'post_author' => $new_exam_owner, 'post_content' => '', 'post_excerpt' => '', 'post_name' => $parent_exam_name . '-' . $new_exam_title, 'post_password' => '', 'post_status' => 'private', 'post_title' => $parent_exam_name . '-' . $new_exam_title, 'post_type' => 'exam', 'to_ping' => '', 'menu_order' => ''); //insert post $new_exam_id = wp_insert_post( $new_exam, $wp_error ); //update post parent update_post_meta($new_exam_id, '_wpcf_belongs_training_id', $exam_belongs_to_training); //query all questions (childs of Mother-Exam) and return only the ones with parent same as question in loop $all_questions = get_posts(array( 'numberposts' => -1, 'post_type' => 'question', 'meta_key' => '_wpcf_belongs_exam_id', 'meta_value' => $belongs_to_parent_exam) ); //if it returns some, get data from those one for each (all data of all those questions), and duplicate them with post_data if( $all_questions ){ foreach( $all_questions as $single_question ){ //get each questions post data $single_question_parent_exam = get_post_meta($single_question, '_wpcf_belongs_training_id'); $possible_score = get_post_meta($single_question->ID, 'wpcf-possible-maximum-score'); //Duplicate (insert) each new question $new_question = array( 'ID' => '', 'comment_status' => $single_question->comment_status, 'ping_status' => $single_question->ping_status, 'post_author' => $new_exam_owner, 'post_content' => '', 'post_excerpt' => '', 'post_name' => $single_question->post_name . '-' . $new_exam_title, 'post_password' => '', 'post_status' => 'publish', 'post_title' => $single_question->post_title . '-' . $new_exam_title, 'post_type' => 'question', 'to_ping' => '', 'menu_order' => ''); $new_question_id = wp_insert_post( $new_question ); update_post_meta($new_question_id, '_wpcf_belongs_exam_id', $new_exam_id); update_post_meta($new_question_id, 'wpcf-possible-maximum-score', $possible_score); //Now duplicate all post meta of each new question $post_meta_data = get_metadata('question', $single_question->ID) if (count($post_meta_data)!=0) { foreach ($post_meta_data as $meta) { update_post_meta($new_exam_id, $meta->meta_key, addslashes($meta->meta_value)); } } } } } } add_action('cred_save_data', 'create_exams_save_data_action',10,2); ,而是返回有状态的Promise object

因此,不是返回data而是为这本书返回承诺

books

然后在使用代码时,您将使用此包装器对象以及基础状态控制机制,该机制将在书籍加载并可用时继续:

function getBooks(user_id) {
    return BookFactory.getBooks.query({ id: user_id }).$promise;
}

答案 1 :(得分:1)

你需要在这里使用promise概念,控制器函数的testGetBooksMethod将等待服务方法的getBooks完成其调用。为此,您需要从BookFactory.getBooks.query函数返回getBooks承诺。在检索数据之后,将创建书籍。将从getBooks方法返回。在调用getBooks方法时,您需要使用.then函数来继续链承诺,当从getBooks返回数据时,函数将获取从您的服务返回的数据。

function getBooks(user_id) {
    var books = [];
    return BookFactory.getBooks.query({ id: user_id }).$promise.then(function (result) {
        angular.forEach(result, function(i) {
            books.push(i);
        });
        return books;
    });
}

<强>控制器

$scope.testGetBooksMethod = function (user_id) {
    getBooks(user_id).then(function(resut){
        alert(resut.length);
    });
};