简体   繁体   English

如何避免在浏览器 JavaScript 库中包含冗余的承诺实现?

[英]How to avoid including a redundant promise implementations in a browser JavaScript library?

I am writing a JavaScript library for the browser that currently exposes functions that take callback arguments.我正在为浏览器编写一个 JavaScript 库,该库当前公开采用回调参数的函数。 For the next version of the library I would like to have those functions return promises instead.对于库的下一个版本,我希望这些函数返回承诺。 However, I haven't figured out a good way to know which flavor of promises (if any) exist in the client app.但是,我还没有想出一个好方法来了解客户端应用程序中存在哪种承诺(如果有)。

I could say my library requires the use of a Promise polyfill, but promise libraries like Bluebird, Q, and RSVP don't always create a Promise global.我可以说我的库需要使用 Promise polyfill,但是像 Bluebird、Q 和 RSVP 这样的Promise库并不总是创建一个Promise全局Promise So then apps that depend on my library would have to either add a redundant promise polyfill, or expose their library's implementation to the global namespace like因此,依赖于我的库的应用程序将不得不添加一个冗余的承诺 polyfill,或者将其库的实现公开给全局命名空间,例如

import RSVP from 'rsvp';

window.Promise = RSVP.Promise

I'm having a hard time finding any examples of a good way to avoid including redundant promise implementations.我很难找到避免包含冗余承诺实现的好方法的任何示例。 The closest thing I've seen is https://github.com/agershun/alasql/blob/develop/src/18promise.js , which will use the app's global promise if it exists, but also includes an inlined copy of the es-6-promise polyfill.我见过的最接近的是https://github.com/agershun/alasql/blob/develop/src/18promise.js ,它将使用应用程序的全局承诺(如果存在),但包括 es 的内联副本-6-promise polyfill。

There are basically three situations you have to deal with:基本上有三种情况你必须处理:

1. There is a global Promise already defined and the caller of your library does not provide a different one. 1. 已经定义了一个全局Promise并且您的库的调用者没有提供不同的Promise In that case, you should be able to detect the existing global implementation and just use it without any other intervention.在这种情况下,您应该能够检测现有的全局实现并直接使用它而无需任何其他干预。 This is what the world looks like in modern browsers today and into the future so this is a good case to handle well.这就是当今和未来现代浏览器中世界的样子,因此这是一个很好处理的案例。

2. There is no global Promise defined and the caller of your library does not provide one to you. 2. 没有定义全局Promise并且你的库的调用者没有提供给你。 If you intend to support this case, then you need to either have a polyfill already built-in or be able to dynamically load one.如果您打算支持这种情况,那么您需要已经内置了一个 polyfill,或者能够动态加载一个 polyfill。 I would recommend dynamically loading Bluebird since it is 100% ES6 compatible, is available via a CDN (easy to dynamically load), dynamically loading would avoid duplicate implementations and Bluebird has many other useful benefits too .我建议动态加载 Bluebird,因为它 100% 兼容 ES6,可通过 CDN 获得(易于动态加载),动态加载将避免重复实现,并且 Bluebird 也有许多其他有用的好处

3. The caller of your library wants to provide you a specific promise implementation that they have already loaded. 3. 你的库的调用者想要为你提供他们已经加载的特定承诺实现。 This other implementation may or may not be defined as the global Promise .这个其他实现可能会也可能不会被定义为全局Promise In this case, you would usually have an optional setting or init for your library that allows the developer to tell you which promise library to use before any of your other API functions are called.在这种情况下,您通常会为您的库setting一个可选settinginit ,以允许开发人员在调用任何其他 API 函数之前告诉您要使用哪个 Promise 库。 You store that away in your own storage and just use that everywhere in your code.您将其存储在您自己的存储中,然后在代码中的任何地方使用它。

You can be very developer-friendly and flexible by supporting all three of these options.通过支持所有这三个选项,您可以对开发人员非常友好和灵活。 It requires only a little code on your part.它只需要您编写少量代码。 First, you offer an API for setting which Promise implementation to use and you store that implementation in your module and you use that everywhere.首先,您提供一个 API 来设置要使用的 Promise 实现,并将该实现存储在您的模块中,并在任何地方使用它。 Then, if that API is not called to set a specific implementation, you detect if the global Promise is there.然后,如果未调用该 API 来设置特定实现,则您会检测全局Promise是否存在。 If it is, you use it.如果是,你就使用它。 If not, then you dynamically load Bluebird from a CDN.如果没有,那么您可以从 CDN 动态加载 Bluebird。 That's a fairly small amount of code for very flexible and developer-friendly support and, going forward, it's nice and simple for everyone (you will just default to the build-in ES6 Promise implementation).对于非常灵活和对开发人员友好的支持,这是相当少量的代码,而且,今后,它对每个人来说都很好且简单(您将默认使用内置的 ES6 Promise 实现)。

If you want the bare minimum (and small) ES6 polyfill, there are several available.如果你想要最小的(和小的)ES6 polyfill,有几个可用的。 One I've seen regularly is this one which comes from the RSVP folks, but is designed to be as small as possible 100% compatible ES6 polyfill with no extra features (only 2.6k).我经常看到的一个是来自 RSVP 的人,但被设计为尽可能小,100% 兼容 ES6 polyfill,没有额外的功能(只有 2.6k)。

As an even simpler alternative for you (but less developer-friendly), you could put more of the burden on the developer using your library and just declare that your library requires that a global Promise be defined before initializing your library.作为对您来说更简单的替代方案(但对开发人员不太友好),您可以为使用您的库的开发人员增加更多的负担,只需声明您的库要求在初始化您的库之前定义一个全局Promise In that case, the developer using your library would have to get their own Promise polyfill if they wanted to use your library with older browsers.在这种情况下,使用您的库的开发人员如果想在较旧的浏览器中使用您的库,则必须获得自己的 Promise polyfill。 This obviously puts more of the work back on the developer using yourlibrary and you'd have to check for the presence of a global Promise and, if not present, then throw an exception upon initialization.这显然将更多的工作交给使用您的库的开发人员,您必须检查全局Promise的存在,如果不存在,则在初始化时抛出异常。 I personally would not recommend this alternative.我个人不推荐这种替代方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何避免异步javascript中的冗余代码? - How to avoid redundant code in asynchronous javascript? 处理猫鼬查询,但使用不同的JavaScript Promise实现 - Handling mongoose queries but with different JavaScript Promise implementations 将Javascript库作为具有不同浏览器和Node.js实现的ES6模块发出 - Emit a Javascript library as an ES6 module with different browser and Node.js implementations 如何避免Promise中的回调 - How to avoid a callback in promise 同时使用服务器端和javascript代码时如何避免多余的HTML代码 - How to avoid redundant HTML code when working with both serverside and javascript code 我可以在Parse JavaScript SDK中使用其他promise实现吗? - Can I use other promise implementations in the Parse JavaScript SDK? 如何在 Javascript 中编写接口和实现? - How to write Interfaces and Implementations in Javascript? 如何使用 javascript 找到浏览器高度,包括工具栏和按钮? - How to find the browser height including the toolbars and buttons with javascript? promise 是浏览器的 API 还是 JavaScript 对象? - Is a promise an API of the browser or a JavaScript object? 如何使用JavaScript库Propel在浏览器上绘图 - How to plot on browser by using javascript library propel
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM