如何中止(停止)在循环中执行的承诺链JavaScript

如何中止(停止)在循环中执行的承诺链JavaScript,javascript,promise,async-await,abort,ecmascript-2017,Javascript,Promise,Async Await,Abort,Ecmascript 2017,我有一个web应用程序,其中有两个按钮:“开始下载”和“中止下载”,它们绑定到方法:start()和stop() 1.当用户单击“开始下载”按钮时,应用程序将在数据数组上循环。对于数组中的每个项目,它将调用\u downloadFile()方法,该方法将下载一个文件并返回新承诺(),下载完成后,将开始下一次下载。 2.如果在下载过程中(可能需要很长时间),用户单击了“中止下载”按钮,我想停止下载过程。 如何实现中止功能? 以下是我到目前为止得到的信息? 请注意,由于我使用的是async/awai

我有一个web应用程序,其中有两个按钮:“开始下载”和“中止下载”,它们绑定到方法:
start()
stop()

1.当用户单击“开始下载”按钮时,应用程序将在数据数组上循环。对于数组中的每个项目,它将调用
\u downloadFile()
方法,该方法将下载一个文件并返回
新承诺()
,下载完成后,将开始下一次下载。
2.如果在下载过程中(可能需要很长时间),用户单击了“中止下载”按钮,我想停止下载过程。

如何实现中止功能?
以下是我到目前为止得到的信息?

请注意,由于我使用的是async/await,循环将一直运行,直到承诺得到解决,并且只有在承诺得到解决(或被拒绝)后,下一次迭代才会执行。

异步函数启动(dataArray) { for(设i=0;i { // ... }); } 函数_保存文件(数据) { // .. } 函数_handleError(错误) { 控制台错误(“错误:+错误”); }
设置一个函数可以检查的标志,如果设置了,则抛出。(好吧,你实际上是在代码中将拒绝转换为解决方案,所以也许你不会抛出,只是早点回来。[顺便说一句,我不会这么做])

let stopped=false;//**旗帜
异步函数启动(dataArray)
{
stopped=false;//***重新初始化标志
for(设i=0;i
如果在调用
停止
之前已经下载了某些项目,该怎么办?您的代码按顺序而不是并行地进行下载;浏览器可以并行处理至少两个(如果不是四个的话),这对用户来说可能更快。这没关系。基本上,我想保留已保存的数据,但这并不重要,因为如果我不需要这些数据,我可以在停止时轻松地将其删除flow@T.J.克劳德,是的,我知道下载是按顺序进行的——这是设计的。因为文件数量非常大。尝试并行下载文件将导致一些问题:1-服务器无法处理所有负载,并将在某个时候开始拒绝文件。2-浏览器可能以资源结束(我从浏览器中得到过几次实际错误)。3-在某些情况下,我需要以前下载的信息以备将来下载(订购事宜)。尽管如此,下载是按顺序进行的,而不是并行的,这一事实与撤销无关。不,不是,我只是想我会指出这一点,以防你没有意识到(很多人对这件事的理解不如你)。遗憾的是,JavaScript的本机承诺(以及
await
)没有像一些高级承诺库那样内置对并行并发限制的支持。我喜欢这个简单且易于实现的答案。我将测试它
async function start(dataArray)
{
  for (let i = 0; i < dataArray.length; i++)
  {
    try
    {
      let fileUrl = `http://server-url/${ i }/${ dataArray[i] }.xml`;
      let result = await _downloadFile(fileUrl);
      _saveResult(result);
    }
    catch(e) // promise rejected
    {
      _handleError(e);
    }
  }
}

function stop()
{
  // what goes here?? how do I stop the flow??
}

function _downloadFile(fileUrl)
{
  return new Promise((resolve, reject) =>
  {
    // ...
  });
}

function _saveFile(data) 
{
  // ..
}

function _handleError(error)
{
  console.error("Error: " + error);
}
let stopped = false; // *** The flag
async function start(dataArray)
{
  stopped = false;                                  // *** Re-init the flag
  for (let i = 0; i < dataArray.length; i++)
  {
    try
    {
      let fileUrl = `http://server-url/${ i }/${ dataArray[i] }.xml`;
      let result = await _downloadFile(fileUrl);
      if (stopped) {                                // *** Check the flag
          return;                                   // *** and return
      }
      _saveResult(result);
    }
    catch(e) // promise rejected
    {
      _handleError(e);
    }
  }
}

function stop()
{
  // *** Set the flag
  stopped = true;
}