如何链接多个单独的JavaScript函数

时间:2017-05-25 18:49:09

标签: javascript angularjs promise

我知道之前已经提出了类似的问题,但没有一个例子对我有意义。 (我发现的任何一个都没有以我需要的清晰度为我解释基础知识。)

我有四个AngularJS函数。每个调用REST服务并执行与任何其他函数无关的内容。 E.g。

$scope.step1 = function() { $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
}).success(function (data, status, headers, config) {
    $scope.step1data = data;
}).error(function (data, status, headers, config) {  
    $scope.logError(data);
});};

我想按顺序调用这四个函数

  1. $ scope.step1
  2. $ scope.step2
  3. $ scope.step3
  4. $ scope.step4
  5. 抓住遇到的任何错误。

    我已将代码缩小到下面,但它对我不起作用。任何帮助将不胜感激。

    $scope.step1().then(function() {
        $scope.step2();
    }).then(function() {
        $scope.step3();
    }).then(function() {
        $scope.step4();
    }).catch(function(e) {
        console.log(e);
    });
    

4 个答案:

答案 0 :(得分:2)

您需要将每个步骤函数的承诺返回到Derived回调,以便其产生的承诺等待该承诺:

then()

答案 1 :(得分:1)

首先,更改step1,step2,step3和step4以返回如下所示的承诺:

    $scope.step1 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step2 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step3 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

    $scope.step4 = function() {
    return $http({  
    method: 'GET',  
    url: "http://www/end/point",  
    cache: true,
    headers: { "Accept": "application/jsonp;odata=verbose" }
   })};

然后,将它们链接在一起:

$scope.step1().then(function (step1data) {
  $scope.step1data = step1data;
  $scope.step2().then(function (step2Data) {
    $scope.step2Data = step2Data;
       $scope.step3().then(function (step3Data) {
         $scope.step3Data = step3Data;
         $scope.step4().then(function (step4Data) {
            $scope.step4Data = step4Data;
         });
       });
  });
})

答案 2 :(得分:0)

你需要使用promise,在你的控制器中,你应该注入$ q来处理诺言。

 angularApp.controller('YourController', ['$q', '$scope',
    function ($q, $scope) {

        $scope.firstFunction = function () {
            var deferred = $q.defer();
            //Do things you want here...

            console.log(1);

            deferred.resolve();
            return deferred.promise;
        };

        $scope.secondFunction = function () {
            var deferred = $q.defer();
            //Do things you want here...

            console.log(2);

            deferred.resolve();
            return deferred.promise;
        };

        $scope.firstFunction().then(function () {
            $scope.secondFunction.then(function () {
                console.log(3)
            })
        })
    }]);

上述功能中的控制台日志将打印出来:

1
2
3

答案 3 :(得分:0)

如果您通过nsynjs同步执行代码,则可以将异步函数与JavaScript提供的任何逻辑混合使用。以下是您的代码可能需要转换的方式:

步骤1:将异步函数包装到通用的nsynjs-aware包装器中:

<!DOCTYPE html>
    <html>
        <body>
            <p>Image to use:</p>
            <img id="scream" onload="loadImage()" src="pics/cover.jpg" alt="Test">
            <p>Canvas:</p>
            <canvas id="myCanvas" width="854" height="480" style="border:1px solid #d3d3d3;">
                Your browser does not support the HTML5 canvas tag.
            </canvas>
        <script>
            window.onload = function() {
                // Not used
            }
            /*
            * Upon image load, draw image on canvas
            */ 
            function loadImage(){
                var c = document.getElementById("myCanvas");
                var ctx = c.getContext("2d");
                var img = document.getElementById("scream");
                ctx.drawImage(img, 0,0, img.naturalWidth, img.naturalHeight);
                console.log("Original Image W=" + img.naturalWidth +
                            " H=" + img.naturalHeight); 
            }
        </script>
    </body>
</html>

步骤2.将您的逻辑编写为同步,并将其置于函数中:

// generic function to retrieve url
// ctx is a reference to caller pseudo-thread context
var httpUrl = function(ctx,url,$http) {
    var res={};
    $http({  
        method: 'GET',  
        url: url,  
        cache: true,
        headers: { "Accept": "application/jsonp;odata=verbose" }
    })
    .success(function (data, status, headers, config) {
        res.data = data;
        ctx.resume() // tells nsynjs to resume caller function
    }).error(function (data, status, headers, config) {
        ctx.resume(data) // resume caller function with exception
        // or replace with these 2 lines if you don't want exception
        // res.error = data;
        // ctx.resume()
    });
    return res;
};
getUrl.nsynjsHasCallback = true; // this tells nsynjs engine that it
                                // should pause execution and wait until ctx.resume() is called from callback

步骤3.通过nsynjs运行同步代码:

function synchronousCode(param1, param2) {
    var step1 = function() {
        var data = httpUrl(nsynjsCtx,"nsynjs/examples/data/file1.json").data;
        console.log("data is ready at this point:",data);
        // do staff this data
        return data;
    };
    var step2 = function() {
        var data = httpUrl(nsynjsCtx,"nsynjs/examples/data/file2.json").data;
        console.log("data is ready at this point:",data);
        // do staff this data
        return data;
    };

    console.log( step1(param1) + step2(param2) ); // do more staff with data
}

此处有更多示例:https://github.com/amaksr/nsynjs/tree/master/examples