异步循环不尊重异步

时间:2021-03-02 15:42:02

标签: javascript node.js loops asynchronous promise

我一直在使用异步函数。

我想要完成的事情 - 我正在创建一个批处理函数 (batchGetSubs),它将遍历一组文件,读取 ID,然后发出 API 请求,等待响应( 问题),然后使用格式化数据写入新文件。

问题 - 我尝试了 Async 和 Await,以及推送承诺并尝试使用 Promise.all 来等待承诺得到解决,但没有成功。当前的行为是,在 API 调用实际返回所有数据之前,我获取了 Promise.all 部分中的所有 console.logs。我使用了这些文章作为参考:

代码 -

dsq > rsq - r && dsq <= rsq + r

2 个答案:

答案 0 :(得分:2)

我只检查了您提出问题的第一个函数:

<块引用>

为什么不等待所有回复?

出于几个原因:

  1. 调用 promise 时,Promise.all 数组仍为空。这是因为您只执行 push afterawait,因此 push 异步发生(阅读:稍后)。

  2. 即使 promises 数组被填充,它也不会包含 promises 对象,而是解析值(即 newRecord 值)

  3. 即使 promises 是 promise 的数组,您也没有将该数组正确传递给 Promise.all:您将该数组包装在另一个数组中,然后该数组只有一个条目,并且那个条目不是一个承诺,而是一个数组。

与您的问题无关,但是:

  • 请养成明确声明所有变量的习惯。您没有为 iterationpromisesi 执行此操作。

  • 仅在对返回值执行某些操作时使用 .map。对于纯迭代,请使用 .forEachfor。在这种情况下,您可以使用返回值来扩展 promises 数组。

  • 如果您打算调用 batchGetSubs 并且需要知道一切何时完成,请确保它返回一个有用的 promise:return Promise.all()

以下是对该函数的建议修正:

async function batchGetSubs(data, command) {
    console.time('batchGetSubs')
    let iteration = 1; // Declare!
    let dataArray = []; 
    let promises = []; // declare

    // declare i
    for (let i = iteration; i < totalIterations; i++) {
        let msIds = await loopAndDump(iteration);

        // Use the return value of the map method. No need for async callback
        promises.push(...msIds.map(item => {
            // Get the promise, not the resolved value, as that will come too late:
            return getSubsByTenantId(item);
        }));
    }
    // promises is already an array; don't make it an array of arrays.
    // And: return the resulting promise: it may be useful to the caller.
    return Promise.all(promises).then(() =>  {
        console.log(p1SubscriptionArray),
        console.timeEnd('batchGetSubs')
    });
}

答案 1 :(得分:0)

您同时执行await 然后。 你做一个承诺/然后等待/异步

async function getSubsByTenantId(msTenantId) {
    let newRecord; let subscriptionArray = [];
    let bearerToken = p1BearerToken;
    let totalSubs = 0;
    const subIdConfig = {
        method: 'get',
        url: ``,
        headers: { 'Authorization': bearerToken }
    }
    await delay();
    const r = await axios(subIdConfig)
    const reponse = r.data
    console.log(response)
}

如果你想尝试 catch 这样做:

async function getSubsByTenantId(msTenantId) {
    let newRecord; let subscriptionArray = [];
    let bearerToken = p1BearerToken;
    let totalSubs = 0;
    const subIdConfig = {
        method: 'get',
        url: ``,
        headers: { 'Authorization': bearerToken }
    }
    await delay();
    let r
    try {
      r = await axios(subIdConfig)
    } catch (error) {
     console.log(error)
    }
    const reponse = r.data
    console.log(response)
}