在 JS 中如何实现顺序执行异步函数?

发布于 2024-12-05 12:37:25 字数 3967 浏览 5 评论 0

在 JavaScript 中,顺序执行异步函数通常通过以下几种方法实现:


1. 使用 async/await

async/await 是最直观且现代的方式,可以让代码看起来像是同步的。

async function runSequentially() {
    const result1 = await asyncFunction1();
    console.log(result1);

    const result2 = await asyncFunction2();
    console.log(result2);

    const result3 = await asyncFunction3();
    console.log(result3);
}
runSequentially();
  • asyncFunction1 , asyncFunction2 , 和 asyncFunction3 是返回 Promise 的异步函数。
  • 使用 await 会暂停当前函数的执行,直到 Promise 解决(resolve/reject)。

2. 使用 Promise

async/await 之前,使用 Promise 链是实现顺序执行的主要方式。

asyncFunction1()
    .then(result1 => {
        console.log(result1);
        return asyncFunction2();
    })
    .then(result2 => {
        console.log(result2);
        return asyncFunction3();
    })
    .then(result3 => {
        console.log(result3);
    })
    .catch(error => {
        console.error(error);
    });

3. 使用 forfor...of 循环

当需要对一个数组中的异步任务顺序执行时,可以使用循环结合 async/await

const tasks = [asyncFunction1, asyncFunction2, asyncFunction3];

async function runSequentially() {
    for (const task of tasks) {
        const result = await task();
        console.log(result);
    }
}
runSequentially();

4. 使用 Array.reduce

使用 reduce 实现数组中的异步任务按顺序执行。

const tasks = [asyncFunction1, asyncFunction2, asyncFunction3];

tasks.reduce((promise, task) => {
    return promise.then(() => task().then(result => console.log(result)));
}, Promise.resolve());

5. 用递归实现

递归方式也是一种实现方法。

const tasks = [asyncFunction1, asyncFunction2, asyncFunction3];

function runSequentially(index = 0) {
    if (index >= tasks.length) return Promise.resolve();
    return tasks[index]().then(result => {
        console.log(result);
        return runSequentially(index + 1);
    });
}
runSequentially();

建议

  • 优先使用 async/await ,它的语法更简洁,更容易阅读和维护。
  • 如果你在处理的是复杂的 Promise 链条或需要动态控制时,可以根据需求选择其他方法。

// 模拟异步
function MyRequest(p, deplay) {
  this.p = p
  this.deplay = deplay
  this.setRequest = () => {
    return new Promise(resolve => {
      setTimeout(()=> {
        resolve(this.p)
      },this.deplay)
    })
  }
}

const p1 = new MyRequest(1,1000)
const p2 = new MyRequest(2, 1500)
const p3 = new MyRequest(3, 500)

// 没处理之前 打印出 3 1 2
p1.setRequest().then(res => console.log(res))
p2.setRequest().then(res => console.log(res))
p3.setRequest().then(res => console.log(res))
// -------------------------------------------------
// 第一种方法 Promise.all()
Promise.all([p1.setRequest(),p2.setRequest(),p3.setRequest()]).then((res) => {
  console.log(res); // [1,2,3]
})
// -----------------------------------------------------
//第二种方法 async/await

async function runAsync() {
  console.log(await p1.setRequest());
  console.log(await p2.setRequest());
  console.log(await p3.setRequest());
} 

runAsync() // 1 2 3
// -------------------------------------------------------
// 第三种 链式调用 then 方法
function runThen() {
  return p1.setRequest().then(res => {
    console.log(res); // 1
    return p2.setRequest()
  }).then(res => {
    console.log(res); // 2
    return p3.setRequest()
  }).then(res => {
    console.log(res); // 3
  })
}
runThen()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

已经忘了多久

文章 0 评论 0

15867725375

文章 0 评论 0

LonelySnow

文章 0 评论 0

走过海棠暮

文章 0 评论 0

轻许诺言

文章 0 评论 0

信馬由缰

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文