1 回答
TA贡献1868条经验 获得超4个赞
所以你可以从技术上让它工作,但我不推荐,原因我稍后会解释。
get这是一个将函数作为局部变量的工作示例。get我们在调用回调之前立即分配给该变量。
它将登录上下文保存在其闭包范围内。因为 JavaScript 是单线程的,我们知道在回调运行之前不能再次重新分配变量。
在这里您可以看到它使用随机超时来模拟 http 调用。即使用户和 url 以随机顺序异步执行,它们也会正确配对。(尝试多次运行此代码片段以检查输出是否始终一致。)
const sleep = () =>
new Promise((resolve) => setTimeout(resolve, Math.random() * 1000));
let get;
async function login(username, callback) {
console.log("logging in as", username);
await sleep();
get = async(url) => {
await sleep();
return `/${username}${url}`;
};
callback();
}
Promise.all([
login("Alice", async() => {
console.log(await get("/Active"));
}),
login("Bob", async() => {
console.log(await get("/Build"));
}),
login("Colin", async() => {
console.log(await get("/Compile"));
}),
]);
我不推荐的原因是因为这是非常脆弱的代码。我们必须非常小心,以确保get仅在回调开始时调用该函数。
例如,如果我们跟注sleepthen get,那么所有的赌注都会被取消。我们不知道get正在使用哪个上下文。
const sleep = () =>
new Promise((resolve) => setTimeout(resolve, Math.random() * 1000));
let get;
async function login(username, callback) {
console.log("logging in as", username);
await sleep();
get = async(url) => {
await sleep();
return `/${username}${url}`;
};
callback();
}
Promise.all([
login("Alice", async() => {
await sleep(); // <-- The only change from the code above. DANGER
console.log(await get("/Active"));
}),
login("Bob", async() => {
await sleep();
console.log(await get("/Build"));
}),
login("Colin", async() => {
await sleep();
console.log(await get("/Compile"));
}),
]);
因此,虽然这对于编码来说非常有趣和有趣,但我相信最好的选择就是明确obj
您正在使用的上下文(正如您在问题中已经描述的那样)并让自己免于头痛。
添加回答
举报