問題一:我需要用第一次發(fā)送ajax請求回的資料作為第二次ajax的參數(shù),而第二次的ajax是在第一次ajax的回呼函數(shù)裡發(fā)送的。但是這裡有問題!就是第二次ajax回傳的資料不能賦值給全域物件的屬性,不知道是不是掉到坑裡了。所以想用$q解決。
問題二:那這個例子來說吧,
// $q 是內(nèi)建服務,所以可以直接使用
ngApp.factory('UserInfo', ['$http', '$q', function ($http, $ q) {
return {
query : function() {
var deferred = $q.defer(); // 聲明延后執(zhí)行,表示要去監(jiān)控后面的執(zhí)行
$http({method: 'GET', url: 'scripts/mine.json'}).
success(function(data, status, headers, config) {
deferred.resolve(data); // 聲明執(zhí)行成功,即http請求數(shù)據(jù)成功,可以返回數(shù)據(jù)了
}).
error(function(data, status, headers, config) {
deferred.reject(data); // 聲明執(zhí)行失敗,即服務器返回錯誤
});
return deferred.promise; // 返回承諾,這里并不是最終數(shù)據(jù),而是訪問最終數(shù)據(jù)的API
} // end query
};
}]);
deferred.resolve 是為了延遲執(zhí)行嗎?那如果能在回呼函數(shù)裡面寫邏輯為什麼還要多此一舉的延遲執(zhí)行呢?
問題三:為什麼說deferred.promise回傳的承諾是最終資料api?這個promise的作用是什麼?
問題四:promise.then執(zhí)行邏輯是什麼?
閉關修行中......
在回答你所有的問題之前,我先對你的範例程式碼做些簡單說明! !
你的範例程式碼是一個典型的Promise
的反面教材,其特征就是:無目的的創(chuàng)建deferred
對象,徒增程式碼複雜度。關於這一點,可以看這裡anti-pattern:
糾正問題之後,我們再來回頭談你的問題。
首先,當你意識到自己正在忍受callback hell
的時候,恭喜你,在javascript
這條路上,你算上道兒了。那麼解決之道有哪些呢?我們最近常見的有:
Promise
generator
配合co
async/await
關於這幾種方式的詳細介紹,我沒仔細翻別人的答案(或許有更好的),只能把自己之前寫的貼出來javascript裡的異步
OK,介紹了解決callback hell
的幾種常見方式,再回頭來說你的callback hell
的幾種常見方式,再回頭來說你的Promise
問題
問題一:我需要用第一次發(fā)送ajax請求回的資料作為第二次ajax的參數(shù),而第二次的ajax是在第一次ajax的回呼函數(shù)裡發(fā)送的。但是這裡有問題!就是第二次ajax回傳的資料不能賦值給全域物件的屬性,不知道是不是掉到坑裡了。所以想用$q解決。
既然我們寄望於Promise
能夠解決回調(diào)地獄的問題,拿肯定不會再是使用回調(diào)的方式,你的疑惑是對的,可你的問題是沒有充分理解Promise
能夠解決回調(diào)地獄的問題,拿肯定不會再是使用回??調(diào)的方式,你的疑惑是對的,可你的問題是沒有充分理解
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
這是一個典型的回呼依賴,call2
依賴了call1
的結果。如果用
拿到回傳結果4. 尤其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 });
對象即可; 2.
deferred
對象,call1
和call2
本身返回Promise
對象即可; 2.resolve
幾乎扮演了之前cb
的角色; 3. 當執(zhí)行call1
、call2
時,不塞入回調(diào),而是通過then
拿到返回結果 4. 尤其return call2(param1);
這個地方,真的不要再度嵌套(很多初入Promise
的選手犯的錯),直接返回,下一個then
這裡有幾個要注意的地方,1. 無需不必要的deferred
對象,call1
和call2
本身返回resolve
幾乎扮演了先前cb
的角色; 3. 當執(zhí)行call1
、call2
時,不塞入回調(diào),而是透過
return call2(param1);
這個地方,真的不要再度嵌套(很多初入的選手犯的錯),直接返回,下一個裡就能拿到結果
問題二:那這個例子來說吧then
ngApp.factory('UserInfo', ['$http', '$q', function($http, $q) {
return {
query: function() {
return $http({method: 'GET', url: 'scripts/mine.json'});
}
};
}]);
??調(diào)用的地方,直接用??就好了:??UserInfo
.query()
.then(function(data){
console.log(data);//這不就是結果嘍!
});
第三、四個問題都是源自於對Promise
本身的實現(xiàn)沒概念,我之前寫過一個小教程,教大家自己手寫一個Promise
的簡單實現(xiàn),建議你跟著做做,先對Promise
本身有個大概了解,一步步來手寫一個Promise