When NOT to use promises [closed]

2019-02-04 17:03发布

问题:

After having read dozens of articles on how great es6 promises are and why we should implement them I have been left with the feeling that ALL of my (non-trivial) javascript functions should be promises.

In fact I feel great when writing code using them since I avoid the triangle of doom and seemingly get clear and concise code. (it really makes reasoning about execution much simpler).

What I haven't been able to find is: When do you NOT use promises? When do I avoid using them?

Update:

While I have seen some great points like API consistency I have yet to find a solid NO case. The answer by Lux suggests that operations that fetch event emitters should avoid them since recurring callbacks are incompatible with promises. I do however feel like the answer is still lacking in substance to check it(as correct) right now.

回答1:

Some rules of thumb:

  1. When your method can be synchronous (simple data transformation), then use synchronous code in that method.

    However if the method can be synchronous sometimes, and asynchronous sometimes (multiple code paths based on internal or external state), it should be asynchronous always. Otherwise, you may encounter unexpected subtle discrepancies in how your code behaves in complex scenarios, so it's best to avoid mixing the two attitudes.

    [edit] As noted in comment, when your method is synchronous for now, but you strongly believe it might need to do async work at one point in the future, you might want to use promises from the beginning to avoid costly refactoring.

  2. In general, your API should be consistent, so it's best to either use promises everywhere, or callbacks everywhere. This will make it easier to reason about the code.

  3. If you are writing ultra high performance code and/or need low memory footprint, you may consider not using promises but callbacks, or using a promise library with a focus on performance, like bluebird, instead of the native Promise implementation / general use case polyfill.

  4. [edit] Anyway, new additions to the web platform, like global fetch function, return a Promise, and it seems that in the upcoming future more and more browser built-ins will be operating on promises. So if you're willing to write modern code, you're not going to escape promises.



回答2:

You use promises for one-shot asynchronous operations. Initiate the operation, carry out the operation, notify a caller of completion or results or error and then done for good.

The situations where you do not use promises are those that are different than described above:

  1. When your operation or function is entirely synchronous. Putting an async API (even with promises) on a synchronous operation just makes things more complex than need be.
  2. In place of events that can occur multiple times. For example, you wouldn't use a promise for a button click handler. An eventEmitter or other event-like structure is still a better structure for recurring events.
  3. When you have a callback situation where the callback is designed to be called multiple times (such as reporting progress or providing a plug-in service via callback).
  4. If you're adding one new operation to an API that is already designed some other way (e.g. with traditional callbacks) and API consistency is desired.
  5. If you are targeting older environments that don't natively support Promises (like old browsers) and you're trying to optimize the download size of your code and you're only doing one or two async operations and you aren't using something like jQuery or Angular that already has a form of promises built-in that you can just use. If you're doing any significant amount of async work, then it is likely worth using a Promises polyfill, so this point is only for cases where size is extremely important and there's very little async work.
  6. For situations where the action often does not finish or occur. Promises are an object with state and thus consume some memory. It would not make sense to create thousands of promises to get notified of lots of different things that usually won't occur because this would create thousands of promise objects (usually with their accompanying closures) that would mostly never get used. This is just inefficient memory usage and is probably better served by some sort of event notification. As I said above, promises work best when you initiate an operation, carry out the operation, notify caller of results or error.


回答3:

Well Promises have one use case: async results that only come once.

You don't use Promises if you can return the result in sync, and you still need callbacks for events, because they may occur multiple times.



回答4:

You may decide not to use Promises, if you want your code to run in the browser (which may not have Promises built in) and size REALLY matters, so you can't afford to use Promise shims/libs.



回答5:

Most often promises are used to working easilly with asihnronnous tasks. Sometimes we deliberately do some things to be asynchronous to avoid overloading of the thread, with which we work. We have only one thread per tab. No need to use promises when things that are small or things that can be made with WebWorker.