2015-07-21 84 views
0

在雲代碼背景的工作,我有一種從API獲取信息的一個方法:返回Pase.Query.each承諾()不工作

var getUserPageView=function(userid){ 
    var promise=new Parse.Promise(); 
    Parse.Cloud.httpRequest({ 
     url: 'http://apiip.ch/api.php?date='+ 
     formatDate(new Date()) 
    }).then(function(httpResponse) { 
     // success 
     var text=httpResponse.text; 
     var obj=JSON.parse(text); 
     promise.resolve(parseInt(obj[0][1])); 
    },function(httpResponse) { 
     // error 
     console.error('Request failed with response code ' + httpResponse.status); 
     promise.reject(); 
    }); 
    return promise; 
}; 

因爲我有打電話給所有用戶用於檢索關於一個特定用戶的信息的API。 按照specification of the "each()" function

如果回調函數返回一個承諾,迭代不會繼續下去,直到這個承諾已履行完畢。

我返回一個承諾,當API返回結果時將會實現。

query=new Parse.Query(Parse.User); 
query.each(function(user){ 
    var promise=Parse.Promise().as(); 
    promise=promise.then(function(){ 
     getUserPageView(234).then(function(result){ 
      console.log("User page view:"+ result); 
      //process user with API information 
      promise.resolve("a"); 
     },function(){ 
      console.log("error"); 
     }); 
    }); 

    console.log("user processed"); 
    return promise; 
}).then(function(){ 
    status.success("Credti update successfull."); 
}, function(error){ 
    status.error("Uh oh, something went wrong."); 
}); 

問題是getUserPageView()永遠不會被調用。或者更確切地說,我認爲「each()」函數並不等待承諾實現。這裏有什麼問題?

回答

0

對於初學者來說,Parse.Cloud.httpRequest已經給出了一個承諾,沒必要把它包起來:

var getUserPageView=function(userid){ // not sure why userid is required, it is not used anywhere. 
    return Parse.Cloud.httpRequest({ 
     url: 'http://apiip.ch/api.php?date='+ formatDate(new Date()) 
    }).then(function(httpResponse) { // success    
     var text=httpResponse.text; 
     var obj=JSON.parse(text); 
     return parseInt(obj[0][1]); 
    },function(httpResponse) { // error    
     console.error('Request failed with response code ' + httpResponse.status); 
     throw httpResponse; 
    }); 
}; 

作爲query.each()我真的不知道,只是走的盲刺吧:

query=new Parse.Query(Parse.User); 
query.each(function(user){ 
    return getUserPageView(234).then(function(result){ 
     console.log("User page view:"+ result); //process user with API information 
    },function(){ 
     console.log("error"); 
    });   
}).then(function(){ 
    status.success("Credti update successfull."); 
}, function(error){ 
    status.error("Uh oh, something went wrong."); 
}); 
+0

謝謝你,現在我讓它與您的建議工作。我必須在getUserPageView()。then()函數中添加一個返回結果。所以: 返回getUserPageView(234)。然後(函數(結果){ 的console.log( 「用戶頁面視圖:」 +導致); 返回結果; },函數(誤差){ 的console.log(」錯誤「); }); – Simoyw

0

@ mido22對於第一種方法來說是完全正確的。只需返回httpRequest返回的諾言。要重複,固定他/她修復了一點:

var getUserPageView=function(userid){ 
    return Parse.Cloud.httpRequest({ 
     url: 'http://apiip.ch/api.php?date='+ 
     formatDate(new Date()) 
    }).then(function(httpResponse) { 
     // success 
     var text=httpResponse.text; 
     var obj=JSON.parse(text); 
     return parseInt(obj[0][1]); 
    },function(httpResponse) { 
     // error 
     console.error('Request failed with response code ' + httpResponse.status); 
     return httpResponse; 
    }); 
}; 

關於第二個方法,有什麼遺漏(至少)是從內承諾返回值。 Parse.Promise.when使邏輯更清晰,imo,承諾一系列的承諾,並履行時,他們都履行...

// very handy for iteration and much more 
var _ = require('underscore'); 

query=new Parse.Query(Parse.User); 
query.limit(4); // start out with a small number to make sure it works (all users will eventually run afoul of resource limits) 
query.find().then(function(users){ 
    var promises = _.map(users, function(user) { 
     return getUserPageView(234); 
    }); 
    return Parse.Promise.when(promises); 
}).then(function(){ 
    status.success(_.toArray(arguments)); // when() returns an array of results for each input promise, these are in var args of the success function 
}, function(error){ 
    status.error(error); 
}); 
+0

感謝您對內部承諾增加回報的建議,我錯過了這個細節。我認爲你的代碼也是正確的,但我使用@ mido22的代碼。 – Simoyw

+0

無需解釋SO複選標記。儘管如此,請注意,對於您的項目,「throw」將會終止,因爲沒有捕獲,因此調用者沒有任何錯誤信息(只是您沒有稱爲成功/錯誤的解析錯誤)。此外,您選擇的每個代碼的結構都會拒絕主叫方除消息外的任何積極或消極結果。這適用於雲*程序*(您只需要副作用),但不適用於調用者期望數據的雲*函數*。 – danh