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
您正在使用的上下文(正如您在問題中已經描述的那樣)并讓自己免于頭痛。
添加回答
舉報