0

我有一个用例,我想进行异步调用(认为它类似于 ajax),然后在该调用的成功块中,我想使用父调用生成的 id 在循环中进行一系列异步调用。我的要求是:

  1. 我在哪里放置显示成功吐司的代码?目前我把它放在成功块内的for循环之后,但它有一个问题,它会在子异步调用完成之前被执行,因为for循环不会等待调用并且会立即执行并且代码会去到展示成功的祝酒词。
  2. 如果任何一个子调用失败,则不应发生进一步的调用(从效率的角度来看这更多),而且在这种情况下,我应该能够删除创建的父记录,以便如何处理也?提前致谢!

示例代码片段:

asyncCallA(inputId)
    .then(output => {
        // inputIdsForChildCalls is the list of inputIds for child async 
        // calls
        inputIdsForChildCalls = [do something with output]
        for (let i = 0; i < inputIdsForChildCalls.length; i++) {
            asyncCallB(inputIdsForChildCalls[i])
                .then(output => {
                    // do something
                })
                .catch(error => {
                    // do something with error
                });
        }
        showSuccessToast("Records created successfully!");
    })
    .catch(error => {
        // do something with error
    });
4

4 回答 4

1

因为听起来你想asyncCallB()连续运行,所以如果其中一个失败,你可以避免任何额外的调用,那么这将最容易使用async/await.

为此,您必须将包含函数标记为async允许使用await. 然后,您可以使用await来对异步操作进行排序:

async function someFunc(inputId) {
    try {
        let output = await asyncCallA(inputId);
        // inputIdsForChildCalls is the list of inputIds for child async 
        // calls
        let inputIdsForChildCalls = [do something with output]
        for (let childId of inputIdsForChildCalls) {
            let childResult = await asyncCallB(inputIdsForChildCalls[childId]);
            // process child result here
            // errors in asyncAllB() will have gone to the catch(e) statement below
        }
        showSuccessToast("Records created successfully!");
    } catch(e) {
        // handle error here
        // throw an error here if you want the caller to be able to see the error
    }
}

为了可能获得更快的性能,您可以asyncCallB()如下所示并行运行您的操作,但所有asyncCallB()调用都将运行,即使第一个调用有错误(因为它们都是并行启动的):

async function someFunc() {
    try {
        let output = await asyncCallA(inputId);
        // inputIdsForChildCalls is the list of inputIds for child async 
        // calls
        let inputIdsForChildCalls = [do something with output]
        let allResults = await Promise.all(inputIdsForChildCalls.map(childId => {
            return asyncCallB(childId);
        }));
        // process allResults array here
        // errors will have gone to the catch(e) statement below
        showSuccessToast("Records created successfully!");
    } catch(e) {
        // handle error here
    }
}
于 2020-03-01T18:43:28.187 回答
0

确保异步链接发生的最佳选择是使用 array.reduce 函数,下面是相同的示例代码。

如果您不清楚 array.reduce 和 promise 是如何工作的。我建议你参考这篇文章。

https://developers.google.com/web/fundamentals/primers/promises

以下是您可以使用的示例代码。

asyncCallA(inputId)
    .then(output => {
        // inputIdsForChildCalls is the list of inputIds for child async 
        // calls
        inputIdsForChildCalls = [];

        inputIdsForChildCalls.reduce(function(sequence, Id)
        {
            return sequence.then(function()
          {
             return asyncCallB(Id);
          }).then(function(asyncCallResult)
                {
              //do something
        });
        }, Promise.resolve())

    })
    .then(function()
    {
        showSuccessToast("Records created successfully!");
    })
    .catch(error => {
        // do something with error
    });
于 2020-03-01T16:40:47.660 回答
0
asyncCallA(inputId)
.then(output => {
    inputIdsForChildCalls = [do something with output]
    Promise.all(inputIdsForChildCalls)
        .then(outputs => {
            // do something
            showSuccessToast("Records created successfully!");
        })
        .catch(error => {
            // do something with error
        });
    }
})
.catch(error => {
    // do something with error
});
于 2020-03-01T15:28:46.203 回答
0
asyncCallA(inputId)
    .then(output => {
        inputIdsForChildCalls = [do something with output]
        let syncCalls = [];
        for (let i = 0; i < inputIdsForChildCalls.length; i++) {
            syncCalls.push(asyncCallB(inputIdsForChildCalls[i]));
        }
        Promise.all(inputIdsForChildCalls)
           .then(outputs => {
            // do something
            showSuccessToast("Records created successfully!");
           })
        .catch(error => {
            // do something with error
        });
    })
    .catch(error => {
        // do something with error
    });
于 2020-03-01T15:37:07.587 回答