文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

在JavaScript中从外部解决Promise:实际应用场景

2024-11-29 19:27

关注

强大的实际应用场景

动作(A)等待另一个动作(B)

A正在进行,但用户想做B,而A需要先发生。

例如:社交应用,用户可以创建、保存和发布帖子。就像Medium。

Save status: Not saved

Publish status: Not published

图片

如果用户想在帖子保存时发布怎么办?

解决方案:确保在发布之前帖子已保存。

saveButton.onclick = () => {
  save();
};

publishButton.onclick = async () => {
  await publish();
};

let saveResolve;

let hasSaved = false;

async function save() {
  hasSaved = false;
  saveStatus.textContent = 'Saving...';
  // ✅ Resolve promise from outside
  await makeSaveRequest();
  saveResolve();
  hasSaved = true;
  saveStatus.textContent = 'Saved';
}

async function waitForSave() {
  if (!hasSaved) {
    await new Promise((resolve) => {
      saveResolve = resolve;
    });
  }
}

async function publish() {
  publishStatus.textContent = 'Waiting for save...';
  await waitForSave();
  publishStatus.textContent = 'Published';
  return;
}

图片

当你将这个逻辑抽象成一种Deferred类时,它变得更好:

class Deferred {
  constructor() {
    this.promise = new Promise((resolve, reject) => {
      this.reject = reject;
      this.resolve = resolve;
    });
  }
}

const deferred = new Deferred();

// Resolve from outside
deferred.resolve();

重构✅:

const deferredSave = new Deferred();
let hasSaved = false;

async function save() {
  hasSaved = false;
  saveStatus.textContent = 'Saving...';
  // 🟢 Resolve promise from outside
  await makeSaveRequest();
  saveResolve();
  hasSaved = true;
  saveStatus.textContent = 'Saved';
}

async function waitForSave() {
  if (!hasSaved) await deferredSave.promise;
}

async function publish() {
  // ...
}

它的工作方式与之前完全相同:

图片

Deferred更加清晰,这就是为什么我们有很多类似的NPM库:ts-deferred、deferred、promise-deferred...

图片

将事件流转换为Promise

这是我多次使用过的一个很好的设置。

执行一个异步任务,实际上是在内部等待事件流触发:

// data-fetcher.js
const deferred = new Deferred();

let dataDeferred;
function startListening() {
  dataDeferred = new Deferred();

  eventStream.on('data', (data) => {
    dataDeferred.resolve(data);
  });
}

async function getData() {
  return await dataDeferred.promise;
}

// client.js
const { startListening, getData } = require('./data-fetcher.js');
startListening();
// 🟢 Waits for event to happen once
const data = await getData();

最后的思考

从外部解决Promise可以解锁强大的模式。

它保持你的代码清晰和灵活,从用户操作到事件流。而像ts-deferred这样的库为我们提供了更好的处理方式。

来源:大迁世界内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯