angular.js - angularjs $q的promise 怎么解决嵌套的ajax问题?
阿神
阿神 2017-05-15 17:03:42
0
1
465

问题一:我需要用第一次发送ajax请求回的数据作为第二次ajax的参数,而第二次的ajax是在第一次ajax的回调函数里发送的。但是这里有问题!就是第二次ajax返回的数据不能赋值给全局对象的属性,不知道是不是掉到坑里了。所以想用$q解决。
问题二:那这个例子来说吧,
// $q 是内置服务,所以可以直接使用
ngApp.factory('UserInfo', ['$http', '$q', function ($http, $q) {
return {

query : function() {  
  var deferred = $q.defer(); // 声明延后执行,表示要去监控后面的执行  
  $http({method: 'GET', url: 'scripts/mine.json'}).  
  success(function(data, status, headers, config) {  
    deferred.resolve(data);  // 声明执行成功,即http请求数据成功,可以返回数据了  
  }).  
  error(function(data, status, headers, config) {  
    deferred.reject(data);   // 声明执行失败,即服务器返回错误  
  });  
  return deferred.promise;   // 返回承诺,这里并不是最终数据,而是访问最终数据的API  
} // end query  

};
}]);
deferred.resolve 是为了延迟执行吗?那如果能在回调函数里面写逻辑为什么还要多此一举的延迟执行呢?
问题三:为什么说deferred.promise返回的承诺是最终数据api?这个promise的作用是什么?
问题四:promise.then执行逻辑是什么?

阿神
阿神

闭关修行中......

모든 응답(1)
PHPzhong

모든 질문에 답하기 전에 샘플 코드에 대해 간략하게 설명하겠습니다! !

귀하의 샘플 코드는 Promise의 전형적인 네거티브 교육 자료입니다. 그 특징은 목적 없이 지연 개체를 생성하여 코드의 복잡성만 증가시키는 것입니다. 이에 대한 안티 패턴은 여기에서 확인할 수 있습니다: Promise的反面教材,其特征就是:无目的的创建deferred对象,徒增代码复杂度。关于这点,可以看这里anti-pattern:

纠正问题之后,我们再来回头谈你的问题。

首先,当你意识到自己正在忍受callback hell的时候,恭喜你,在javascript这条路上,你算上道儿了。那么解决之道有哪些呢?我们最近常见的有:

  • Promise

  • generator配合co

  • async/await

关于这几种方式的详细介绍,我没仔细翻别人的答案(或许有更好的),只能把自己之前写的贴出来javascript里的异步

OK,介绍了解决callback hell的几种常见方式,再回头来说你的Promise问题

问题一:我需要用第一次发送ajax请求回的数据作为第二次ajax的参数,而第二次的ajax是在第一次ajax的回调函数里发送的。但是这里有问题!就是第二次ajax返回的数据不能赋值给全局对象的属性,不知道是不是掉到坑里了。所以想用$q解决。

既然我们寄希望于Promise能够解决回调地狱的问题,拿肯定不会再是使用回调的方式,你的疑惑是对的,可你的问题是没有充分理解Promise是这么工作的。我先举个例子:

var call1 = function(cb) {
    setTimeout(function() {
        cb('call1');
    }, 10);
};

var call2 = function(param1, cb) {
    setTimeout(function() {
        cb(param1 + ' + call2');
    }, 10);
};

call1(function(param1) {
    call2(param1, function(param2) {
        console.log(param2); //call1 + call2
    });
});

这是一个典型的回调依赖,call2依赖了call1的结果。如果用Promise改写,应该是什么样子呢?

var call1 = function() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('call1');
        }, 10);
    });
};

var call2 = function(param1) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(param1 + ' + call2');
        }, 10);
    });
};

call1()
    .then(function(param1) {
        return call2(param1);
    })
    .then(function(param2) {
        console.log(param2); //call1 + call2
    });

这里有几个要注意的地方,1. 无需不必要的deferred对象,call1call2本身返回Promise对象即可; 2. resolve几乎扮演了之前cb的角色; 3. 当执行call1call2时,不塞入回调,而是通过then拿到返回结果 4. 尤其return call2(param1);这个地方,真的不要再度嵌套(很多初入Promise的选手犯的错),直接返回,下一个then里就能拿到结果

问题二:那这个例子来说吧

这就是最早说的问题,你过度反应了,明显把简单问题复杂化了,这么写足矣:

ngApp.factory('UserInfo', ['$http', '$q', function($http, $q) {
    return {
        query: function() {
            return $http({method: 'GET', url: 'scripts/mine.json'});
        }
    };
}]);

调用的地方,直接用then

🎜
🎜문제를 해결한 후 귀하의 질문에 다시 답변해 드리겠습니다. 🎜
🎜우선 콜백 지옥을 견디고 있다는 걸 깨닫게 된다면, 축하드립니다. 당신은 javascript의 길에 들어서 있는 것입니다. 그렇다면 해결책은 무엇입니까? 가장 최근에 본 것들은 다음과 같습니다: 🎜
  • 🎜약속🎜
  • 🎜generator는 co🎜
  • 와 협력합니다.
  • 🎜비동기/대기🎜
🎜 이 방법들에 대한 자세한 소개는 다른 분들의 답변을 잘 읽지 않아서(아마도 더 좋은 답변이 있을 수도 있습니다), 제가 전에 작성한 Asynchronous in JavaScript🎜만 게시하겠습니다. 🎜자, 콜백 지옥을 해결하는 몇 가지 일반적인 방법을 소개하고 Promise 문제에 대해 이야기해 보겠습니다🎜 🎜질문 1: 첫 번째 ajax 요청에서 반환된 데이터를 두 번째 ajax의 매개변수로 사용해야 하는데 두 번째 ajax는 첫 번째 ajax의 콜백 함수에서 전송됩니다. 하지만 문제가 있습니다! 단지 두 번째로 ajax에서 반환한 데이터를 전역 개체의 속성에 할당할 수 없다는 것뿐입니다. 그래서 $q를 사용하여 문제를 해결하고 싶습니다. 🎜 🎜우리는 Promise가 콜백 지옥의 문제를 해결할 수 있기를 바라기 때문에 더 이상 콜백을 사용하지 않을 것입니다. 그러나 당신의 문제는 를 완전히 이해하지 못한다는 것입니다. 약속이 작동합니다. 먼저 예를 들어보겠습니다. 🎜 으아악
🎜이것은 일반적인 콜백 종속성입니다. call2call1의 결과에 따라 달라집니다. Promise를 사용하여 다시 작성하면 어떤 모습일까요? 🎜
으아악
🎜여기서 몇 가지 주의할 점이 있습니다. 1. 불필요한 지연 객체가 필요하지 않으며 call1call2 자체가 Promise 객체; 2. resolve는 이전 cb의 역할을 거의 수행합니다. 3. call1을 실행할 때, call2, 콜백을 삽입하지 않고 then을 통해 반환 결과를 얻습니다. 4. 특히 return call2(param1); 이 곳은 정말 필요하지 않습니다. 다시 중첩하고(Promise를 처음 사용하는 많은 플레이어가 범하는 실수) 바로 돌아와서 다음 then🎜
에서 결과를 얻습니다. 🎜질문 2: 이 예를 들어보겠습니다🎜 🎜이것은 첫 번째 질문입니다. 과민반응을 하셔서 간단한 문제를 분명히 복잡하게 만드셨습니다. 🎜 으아악 🎜전화할 곳은 다음을 사용하세요. 🎜으아악

세 번째와 네 번째 질문은 모두 Promise本身的实现没概念,我之前写过一个小教程,教大家自己手写一个Promise的简单实现,建议你跟着做做,先对Promise자체에 대한 일반적인 이해와 Promise를 단계별로 손으로 쓰는 방법

에 기초합니다.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿