为了账号安全,请及时绑定邮箱和手机立即绑定

如何模仿 Jest 描述模式?

如何模仿 Jest 描述模式?

开满天机 2023-07-14 15:43:29
如何在 javascript 中编写login和get函数?我有一种感觉,通过一些内联函数、bind 和这个魔法的混合是可能的。或者说这是不可能的?Promise.all([  login("user1", () => {    console.log(get("/healthy")); // prints "user1/healthy"  }),  login("user2", () => {    console.log(get("/ready")); // prints "user2/ready"  })]);我知道可以这样写。但我很好奇在没有 obj 的情况下编写它。login("user1", (obj) => {  obj.get("/ready");});这不是类似于 Jest 编码描述/它模式的方式吗?describe("Login test", () => {  test("Login", async () => {    expect("ready").toEqual("ready");  });});
查看完整描述

1 回答

?
MYYA

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您正在使用的上下文(正如您在问题中已经描述的那样)并让自己免于头痛。



查看完整回答
反对 回复 2023-07-14
  • 1 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信