递归异步/等待

时间:2021-06-11 01:37:45

标签: javascript node.js recursion

我有一个调用 OneDrive API 的函数。此 API 按每页 200 个项目对其数据进行分页。因此,当响应有另一个页面时(当 @odata.nextLink 位于响应数据中时被识别),我会循环浏览这些页面。这工作正常,但我宁愿不使用迭代循环。我想我应该能够递归调用我的函数并连接数据,但我不确定如何在不每次都覆盖我的数据的情况下做到这一点。

这是我当前的代码:

async getFiles(storage, auth) {
        let url = `${auth.meta.serviceEndpointUri}/drives/${storage.meta.driveId}/items/${storage.meta.id}/children`;
        let files = [];
        let nextLink;
        try {
            do {
                const request = {
                    url,
                    method:'get',
                    headers:{
                        Accept: 'application/json',
                        Authorization: 'Bearer ' + authorization.access_token
                    }
                }
                const result = await axios(request);

                if(!result || (result && result.status !== 200)) {
                    // throw error here
                }

                const values = _.get(result.data, 'value', []);
                nextLink = _.get(result.data, '@odata.nextLink');
                files = files.concat(values);
                if (nextLink) {
                    url = nextLink;
                }

            } while (nextLink);

            return files;
        } catch (err) {
            // throw error here
        }
    };

有没有一种方法可以改变它以不再使用循环,而是使用异步/等待并使用新的页面 url 递归调用 getFiles,同时每次仍然连接 files?< /p>

1 个答案:

答案 0 :(得分:2)

似乎这是一个相对简单的转换。制作一个单独的函数来执行递归逻辑。

const getAllFiles = async (storage, auth) => {
    const url = `${auth.meta.serviceEndpointUri}/drives/${storage.meta.driveId}/items/${storage.meta.id}/children`;
    try {
        return await getFiles(url);
    } catch (err) {
        // handle error here
        // if you only want to re-throw, omit the try/catch entirely
    }
};

const getFiles = async (url, files = []) => {
    const request = {
        url,
        method: 'get',
        headers: {
            Accept: 'application/json',
            Authorization: 'Bearer ' + authorization.access_token
        }
    };
    const result = await axios(request);

    if (!result || (result && result.status !== 200)) {
        // throw error here
    }

    const values = _.get(result.data, 'value', []);
    nextLink = _.get(result.data, '@odata.nextLink');
    files.push(values);
    if (nextLink) {
        getFiles(nextLink, files)
    }
    return files;
}

您可能希望完全省略 catch 中的 getAllFiles,而是让错误渗透到调用方。