按顺序执行函数?不知道如何准确描述这个问题



我在尝试解决它时遇到了一个问题;但不知何故卡在了中间。问题是实现一个函数 $do((,它可以接受任意数量的函数并按调用顺序执行它们。 在具体示例中,在 700 毫秒内打印 a,在 200 毫秒内打印 b,然后在 100 毫秒内打印 c。挑战部分是虽然 c 应该先打印,但在 $do(( 中调用 a 和 b 之后调用它。 我的实现如下,几乎可以工作,但由于某种原因无法打印c。需要帮助。多谢。

const a = (cb) => {
setTimeout(() => {
cb();
console.log('a', 700);
}, 700);
};
const b = (cb) => {
setTimeout(() => {
cb();
console.log('b', 200);
}, 200);
};

const c = (cb) => {
setTimeout(() => {
cb();
console.log('c', 100);
}, 100);
};
const stores = [];
let running = false;
function $do() {
const cbs = Array.prototype.slice.call(arguments);
stores.push(cbs);
let i = 0;
while (stores.length > 0 && !running) {
let head = stores.shift();
running = i < head.length;
head.forEach((cb) => {
cb(() => {
i++;
running = i < head.length;
console.log(running);
});
});
}
}
$do(a, b);
$do(c);

此解决方案使用闭包和Promise.all()来等待之前挂起的每个$do()调用完成,然后再调用当前调用中提供的每个函数。

这意味着在ab都回拨之前不会调用c

const delay = (name, ms) => cb => {
setTimeout(() => {
cb()
console.log(name, ms)
}, ms)
}
const a = delay('a', 700)
const b = delay('b', 200)
const c = delay('c', 100)
const $do = (() => {
let done = Promise.resolve()
return (...fns) => {
done = done.then(
() => Promise.all(fns.map(fn => new Promise(fn)))
)
}
})()
$do(a, b)
$do(c)

使用下面的 IIFE 只是为了避免不必要地污染全局命名空间

我不确定的一件事是将数组推送到存储中 - 如果没有"处理",数组最终会

[[a, b],[c]]

您需要的处理将是 a,然后是 b,然后是 c - 因此商店可以很容易地

[a, b, c]

顺便说一下,这就是下面的代码所做的

const a = (cb) => {
setTimeout(() => {
cb();
console.log('a', 700);
}, 700);
};
const b = (cb) => {
setTimeout(() => {
cb();
console.log('b', 200);
}, 200);
};
const c = (cb) => {
setTimeout(() => {
cb();
console.log('c', 100);
}, 100);
};
// NOTE: I only use the IIFE to not polute GLOBAL namespace with stores and running variables
const $do = (() => {
const stores = [];
let running = false;
let process = () => {
const cb = stores.shift();
cb(() => {
running = !!stores.length;
if (running) {
process();
}
});
};
return (...cbs) => {
stores.push(...cbs);
if (!running) {
running = true;
process();
}
};
})();
$do(a, b);
$do(c);

最新更新