如何解决如何按顺序执行异步任务
我目前正在 Javascript 中试验异步函数,我偶然发现了一个案例,我想按照它们在数组中的顺序执行一组异步函数。
我还希望能够将参数传递给异步函数。以我当前的solution,先执行两个带参数的函数,然后同时执行其他两个函数。
const asyncOne = async (value = "no value passed to async 1") => {
return new Promise((resolve,reject) => {
setTimeout(() => {
console.log(value);
resolve();
},1000);
});
};
const asyncTwo = async (value = "no value passed to async 2") => {
return new Promise((resolve,1000);
});
};
const sequence = async tasks => {
const resolve = Promise.resolve(null);
await tasks.reduce(
(promise,task) =>
promise.then(() => (typeof task === "function" ? task() : task)),resolve
);
};
(async () => {
const res = await sequence([asyncOne("first"),asyncTwo,asyncOne,asyncTwo("last")]);
})();
预期输出:
"first"
"no value passed to async 2"
"no value passed to async 1"
"last"
实际输出:
"first"
"last"
"no value passed to async 2"
"no value passed to async 1"
解决方法
正如我在评论中提到的,您不应将 new Promise
与 async
混用 - 没有必要,您只会混淆您自己和任何未来的读者。
无论哪种方式,async
函数都将开始同步执行,这就是您看到序列的原因(first
和 last
超时同时开始)。要解决此问题,您需要使用一个函数来调用返回承诺的函数,如下所示:
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve,ms));
}
async function asyncOne(value = "async1 default") {
await delay(1000);
console.log(value);
}
async function asyncTwo(value = "async2 default") {
await delay(1000);
console.log(value);
}
async function sequence(tasks,init = undefined) {
let value = init;
for (let task of tasks) {
if (typeof task === "function") value = await task(value);
else value = await task;
}
return value;
}
(async () => {
await sequence([
() => asyncOne("first"),asyncTwo,asyncOne,asyncTwo.bind(this,"last"),// can also use `bind` instead of an anonymous arrow function
]);
})();
此实现还允许您将值从一个承诺链接到另一个承诺,并允许将初始值传递给第一个承诺返回函数,á la
await sequence([asyncTwo],"hello!");
,
asyncOne("first")
和 asyncTwo("last")
调用函数并立即执行它们,因此它会阻止您按顺序执行它们。
改为编写 asyncOne.bind(this,"first")
,它不会立即执行函数,而是允许您稍后执行。
(async () => {
const functions = [
asyncOne.bind(this,"first"),"last")
];
for(let f of functions){
await f()
}
})();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。