[英]Using Promise.all() for multiple http/oauth queries
我正在嘗試等待對API的兩個OAuth調用的輸出,並且在從這些調用中檢索數據時遇到了麻煩。 如果我使用Promise.all(call1,call2).then(),我將獲得有關請求對象的信息。
首先,這是fitbit_oauth對象的設置:
var fitbit_oauth = new OAuth.OAuth(
'https://api.fitbit.com/oauth/request_token',
'https://api.fitbit.com/oauth/access_token',
config.fitbitClientKey,
config.fitbitClientSecret,
'1.0',
null,
'HMAC-SHA1'
);
foodpath = 'https://api.fitbit.com/1/user/-/foods/log/date/' + moment().utc().add('ms', user.timezoneOffset).format('YYYY-MM-DD') + '.json';
activitypath = 'https://api.fitbit.com/1/user/-/activities/date/' + moment().utc().add('ms', user.timezoneOffset).format('YYYY-MM-DD') + '.json';
Promise.all([fitbit_oauth.get(foodpath, user.accessToken, user.accessSecret),
fitbit_oauth.get(activitypath, user.accessToken,
user.accessSecret)])
.then(function(arrayOfResults) {
console.log(arrayOfResults);
}
我希望arrayOfResults給我來自調用的數據,而不是有關請求的信息。 我在這里做錯了什么? 我是諾言的新手,所以我確信這對不熟悉的人來說很容易。
單個fitbit_oauth調用的回調如下:
fitbit_oauth.get(
'https://api.fitbit.com/1/user/-/activities/date/' + moment().utc().add('ms', user.timezoneOffset).format('YYYY-MM-DD') + '.json',
user.accessToken,
user.accessSecret,
function (err, data, res) {
if (err) {
console.error("Error fetching activity data. ", err);
callback(err);
return;
}
data = JSON.parse(data);
console.log("Fitbit Get Activities", data);
// Update (and return) the user
User.findOneAndUpdate(
{
encodedId: user.encodedId
},
{
stepsToday: data.summary.steps,
stepsGoal: data.goals.steps
},
null,
function(err, user) {
if (err) {
console.error("Error updating user activity.", err);
}
callback(err, user);
}
);
}
);
多虧了jfriend00,我才能完成這項工作,下面是新代碼:
function fitbit_oauth_getP(path, accessToken, accessSecret) {
return new Promise (function(resolve, reject) {
fitbit_oauth.get(path, accessToken, accessSecret, function(err, data, res) {
if (err) {
reject(err);
} else {
resolve(data);
}
}
)
})};
Promise.all([fitbit_oauth_getP(foodpath, user.accessToken, user.accessSecret),
fitbit_oauth_getP(activitypath, user.accessToken, user.accessSecret)])
.then(function(arrayOfResults) {
console.log(arrayOfResults);
});
Promise.all()
僅在異步函數的返回promise且異步操作的結果成為promise的已解決(或拒絕)值時才可以正確使用。
Promise.all()
中沒有魔術可以以某種方式知道fitbit函數何時完成(如果它們不返回promise)。
您仍然可以使用Promise.all()
,但是您需要“承諾化” fitbit函數,該函數是圍繞它們的一個小包裝,這將使它們的常規回調方法返回返回的諾言,然后根據回調結果解決或拒絕該諾言。
有關創建約定的包裝的一些參考:
如果您有一個異步函數接受一個回調來提供異步結果,例如fs.rename(oldPath, newPath, callback)
,那么您可以像這樣“承諾”它:
function renameP(oldPath, newPath) {
return new Promise(function(resolve, reject) {
fs.rename(oldPath, newPath, function(err) {
if (err) {
reject(err);
} else {
resolve();
}
});
});
};
renameP("orig.txt", "backup.txt").then(function() {
// successful here
}, function(err) {
// error here
});
一些承諾庫(例如Bluebird)具有內置的.promisify()
方法,該方法將為您執行此操作(它將返回一個函數存根,可以在遵循node.js異步調用約定的任何函數上調用該函數存根)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.