How can I tell if an object is an Angular $q promise?

后端 未结 3 1991
天命终不由人
天命终不由人 2021-01-18 18:03

I have a pre-existing non-Angular API library in my project. It has a .request method which returns jQuery.Deferred promises. I created a simple Angular service

3条回答
  •  广开言路
    2021-01-18 18:35

    As a partial solution, adequate and appropriate for the given example, we can easily distinguish between jQuery.Deferred promises and Angular promises by checking for the presence of specific methods. For instance, Angular's $q promises have the method catch to handle errors, while jQuery.Deferred's promises have the method fail.

    function promiseIsAngularOrJQuery(promise) {
        if (typeof promise.fail === 'function') {
            return 'jquery';
        } else if (typeof promise.catch === 'function') {
            return 'angular';
        } else {
            throw new Error("this can't be either type of promise!");
        }
    }
    

    However, using this technique to distinguish between more different types of promises, or between promises and non-promises, could get very messy. Different implementations often use use many of the same method names. It could probably be made to work, but I'm not going down that road.


    There is an alternative that should be able to reliably identify $q promises under reasonable conditions: operating on trusted objects in a non-hostile environment, with only a single version of Angular in use. However, some might see it as too "hacky" for serious use.

    If you convert a function to a string using the String() function, the result is the source code for that function. We just need to use this to compare the .then method on a potential promise object to the .then method of a known $q promise object:

    function isAngularPromise(value) {
        if (typeof value.then !== 'function') {
            return false;
        }
        var promiseThenSrc = String($q.defer().promise.then);
        var valueThenSrc = String(value.then);
        return promiseThenSrc === valueThenSrc;
    }
    

提交回复
热议问题