Is there a shortcut to proxy-resolve/reject a prom

2020-02-12 14:13发布

Given an unresolved deferred (dfd), and a then-able promise (promise), which may or may not be deferred, is there a way to 'proxy' the promise into the deferred?

The semantics should be as so:

promise.then(dfd.resolve, dfd.reject);

The $q documentation only mentions handling of rejected promises (and furthermore, only promises rejected in a certain way):

defered.resolve(value) – resolves the derived promise with the value. If the value is a rejection constructed via $q.reject, the promise will be rejected instead.

This makes it unclear if dfd.resolve(promise) is valid/supported. Also, I cannot use $q.when (which does take a then-able) because the promise of the defered has already been returned.

The Angular version is 1.2.x.

2条回答
Viruses.
2楼-- · 2020-02-12 14:52

Yes, deferred.resolve takes a promise.

deferred.resolve(value)

Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does).

Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason.

Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value.

Calling resolve with a non-promise value causes promise to be fulfilled with that value.

From the Q API Reference

To answer another part of your question:

""This makes it unclear if dfd.resolve(promise) is valid/supported. Also, I cannot use $q.when (which does take a then-able) because the promise of the defered has already been returned.""

The promise created by deferred.promise can be given to more that one recipient. Each recipient can call the .then method on that promise. The promise can only be resolved once (either to a value or an error). But the container can be read by more that one consumer.

Think of a promise as a container for a value which you can get in the future by the .then, .catch, and .finally methods. You can visit the container more than once but its contents are immutable when it resolves.

Deprecation of the .success and .error methods in the $http service

The AngularJS team in their new found wisdom have decided to deprecate the .success and .error methods. Those methods were buggy and I say good riddance.

For more information on the deprecation (or should I say failure) of the .success and .error methods visit the latest AngularJS $http Service API Docs.

We should avoid the .success and .error methods and learn to use the .then, .catch, and .finally from now on.

The $q service reference cited by the OP is dated. For the latest version, visit AngularJS $q Service API Docs.

UPDATE for Legacy AngularJS v1.2

I did some spelunking in the AngularJS Github. The legacy $http service creates a $q promise (L750) and subsequently attaches the buggy .success method (L769) and the buggy .error method (L776).

What this means is that people stuck with using the older version of AngularJS can start migrating to the .then, .catch, and .finally methods.

An example with two consumers of the same $http promise.

//Producer
var httpPromise = $http.get(url);

//Consumer #1
httpPromise.then (function (response) {
                vm1.data = response.data;
        }) .catch (function (err) {
                //check for error
        });

//Consumer #2
httpPromise.then (function (response) {
                vm2.data = response.data;
        }) .catch (function (err) {
                //check for error
        });

Notice that the .then method returns data differently than the .success method.

Also both consumers should check for errors.

So even users of legacy AngularJS can start writing .success and .error free code.

查看更多
▲ chillily
3楼-- · 2020-02-12 15:11

Yes.

Any time you resolve a promise to another promise (whether by resolve() or by returning from a callback), it will implicitly wait for that other promise.

In fact, it is impossible to make a promise actually resolve to another promise instance (without waiting).

查看更多
登录 后发表回答