簡體   English   中英

使用Promise.all()進行多個http / oauth查詢

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM