1 回答

TA貢獻(xiàn)1868條經(jīng)驗(yàn) 獲得超4個(gè)贊
所以你可以從技術(shù)上讓它工作,但我不推薦,原因我稍后會(huì)解釋。
get這是一個(gè)將函數(shù)作為局部變量的工作示例。get我們在調(diào)用回調(diào)之前立即分配給該變量。
它將登錄上下文保存在其閉包范圍內(nèi)。因?yàn)?JavaScript 是單線程的,我們知道在回調(diào)運(yùn)行之前不能再次重新分配變量。
在這里您可以看到它使用隨機(jī)超時(shí)來模擬 http 調(diào)用。即使用戶和 url 以隨機(jī)順序異步執(zhí)行,它們也會(huì)正確配對。(嘗試多次運(yùn)行此代碼片段以檢查輸出是否始終一致。)
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"));
}),
]);
我不推薦的原因是因?yàn)檫@是非常脆弱的代碼。我們必須非常小心,以確保get僅在回調(diào)開始時(shí)調(diào)用該函數(shù)。
例如,如果我們跟注sleepthen get,那么所有的賭注都會(huì)被取消。我們不知道get正在使用哪個(gè)上下文。
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
您正在使用的上下文(正如您在問題中已經(jīng)描述的那樣)并讓自己免于頭痛。
添加回答
舉報(bào)