首页 > 解决方案 > async await,一次处理一项For循环

问题描述

我似乎无法理解异步等待,假设我想一次处理一个数组的一项,延迟 1 秒:

    myfunction() {   
        clearTimeout(this.timer);

        this.timer = setTimeout(() => {              
            for (const item of this.myarray) {       
                 this.dosomething(item).then((res: string) => {
                     setTimeout(() => {
                         await this.final_thing_before_the_next_item.push(res);
                     }, 1000);
                 });
           }       
        }, 200);        
    }

我会把“异步”放在哪里?

标签: javascriptangulartypescriptasync-await

解决方案


如果我正确理解您的问题(和代码示例),您基本上想要

  • 睡眠 200 毫秒
  • 遍历项目列表。对于您想要的每个项目:
    • 调用一个函数,将当前项目传递给它并获得响应作为回报。
    • 暂停 1 秒钟。
    • 调用第二个函数,将响应传递给它

为此,您需要一个sleep()函数,该函数返回一个承诺,该承诺将在指定时间过去后解决:

function sleep(ms = 1000) {
  const p = new Promise( (resolve, reject) => {
    setTimeout(() => resolve());
  });
  return p;
}

有了它,您需要一个async函数来完成实际工作。必须是async因为这就是让它做await其他事情的原因:

async function process_items( items, delayInMs = 1000 ) {
  for ( item of items ) {
    const res = await doSomething( item, delayInMs );
    await sleep(delay);
    await doSomethingElse( res );
  }
}

从上面的代码可以看出,使用async/await优于回调或 Promise 链的优势在于它为您提供了更简洁和声明性的语法。

然后你可以把它全部包装在另一个async函数中:

async function myfunction() {
  await sleep(200);
  await process_items( this.myarray, 1000 );
}

将函数标记为async做两件事:

  • 启用await在该函数内的使用,以及
  • 将函数转换为返回 Promise 的函数,而不管其表面上的返回值是什么。

如果您采用此功能:

function foo() {
  return 1;
}

并将其标记为async

async function foo() {
  return 1;
}

(或多或少)好像您已更改为:

function foo() {
  return Promise.resolve(1);
}

推荐阅读