最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I transfer a promise resolve() to another promise - Stack Overflow

programmeradmin2浏览0评论

Let's say I have a "JsonEditor" module (just for the example) which has 3 functions: get(), setProperty() and save().

Here is the code (the question follows):

var fs   = require('fs')
  , q    = require('q');

var jsonEditorModule = (function() {
    return {
        get: function(jsonPath) {
            // ...
        },

        save: function(jsonObject, jsonPath) {
            var qJson = q.defer();

            var jsonContent = JSON.stringify(jsonObject, null, 2);

            fs.writeFile(jsonPath, jsonContent, function(err) {
                if(err) {
                    qJson.reject(err);
                }
                else {
                    qJson.resolve();
                }
            });

            return qJson.promise;
        },

        setProperty: function(prop, value, jsonPath) {
            var self = this;
            var qJson = q.defer();

            this.get(jsonPath)
            .then(
                function(jsonObject) {
                    // Set the property
                    jsonObject[prop] = value;

                    // Save the file
                    self.save(jsonObject, jsonPath)
                    .then(
                        function() {
                            qJson.resolve();
                        },
                        function() {
                            qJson.reject();
                        },
                    );
                }
            );

            return qJson.promise;
        },
    };
})();

module.exports = jsonEditorModule;

See the then() right after the save() in the setProperty() function ?

It looks stupid, right ?

Do I need to manually resolve() and reject() my promise ? Can't I just transfer the save() behavior to my setProperty() promise ?

Hope the question is clear enough (and not too stupid).

Thanks

Let's say I have a "JsonEditor" module (just for the example) which has 3 functions: get(), setProperty() and save().

Here is the code (the question follows):

var fs   = require('fs')
  , q    = require('q');

var jsonEditorModule = (function() {
    return {
        get: function(jsonPath) {
            // ...
        },

        save: function(jsonObject, jsonPath) {
            var qJson = q.defer();

            var jsonContent = JSON.stringify(jsonObject, null, 2);

            fs.writeFile(jsonPath, jsonContent, function(err) {
                if(err) {
                    qJson.reject(err);
                }
                else {
                    qJson.resolve();
                }
            });

            return qJson.promise;
        },

        setProperty: function(prop, value, jsonPath) {
            var self = this;
            var qJson = q.defer();

            this.get(jsonPath)
            .then(
                function(jsonObject) {
                    // Set the property
                    jsonObject[prop] = value;

                    // Save the file
                    self.save(jsonObject, jsonPath)
                    .then(
                        function() {
                            qJson.resolve();
                        },
                        function() {
                            qJson.reject();
                        },
                    );
                }
            );

            return qJson.promise;
        },
    };
})();

module.exports = jsonEditorModule;

See the then() right after the save() in the setProperty() function ?

It looks stupid, right ?

Do I need to manually resolve() and reject() my promise ? Can't I just transfer the save() behavior to my setProperty() promise ?

Hope the question is clear enough (and not too stupid).

Thanks

Share Improve this question asked Mar 5, 2015 at 15:15 MaslowMaslow 1,1049 silver badges23 bronze badges 1
  • Look here and see if you can rework you call structure to set up a chain stackoverflow./questions/12461589/… – Steve Mitcham Commented Mar 5, 2015 at 15:20
Add a ment  | 

2 Answers 2

Reset to default 2

What you want to achieve is described here: chaining, basically if a handler returns a promise (let's call it innerPromiseFromHandler) then the handlers of the .then which was defined on the previous promise will be executed when the innerPromiseFromHandler gets a resolution value:

var jsonEditorModule = (function() {
  return {
    get: function(jsonPath) {
      return Q.delay(1000).then(function () {
        document.write('get...<br/>');
        return 'get';
      });
    },

    save: function(result) {
      return Q.delay(1000).then(function () {
        document.write('save...<br/>');        
        return result + ' save';
      });
    },

    setProperty: function(prop, value, jsonPath) {
      return this.get(jsonPath)
        .then(function(result) {
          return jsonEditorModule.save(result);
        });
    }
  };
})();
      
jsonEditorModule
  .setProperty()
  .then(function (result) {    
    document.write(result + ' finish');
  })
<script src="http://cdnjs.cloudflare./ajax/libs/q.js/0.9.2/q.js"></script>

It looks stupid, right? Do I need to manually resolve() and reject() my promise?

Right, and in fact this has an own name: Manually resolving/rejecting an extra promise is known as the stupid deferred antipattern.

Can't I just transfer the save() behavior to my setProperty() promise?

Yes, this is trivially possible - and it's builtin to the then method: Calling .then() returns a new promise for the return value of your callbacks, even if that value is hidden in a promise.

var jsonEditorModule = {
    get: function(jsonPath) {
        // ...
    },
    save: function(jsonObject, jsonPath) {
        return Q.ninvoke(fs, "writeFile", jsonPath, JSON.stringify(jsonObject, null, 2));
    },
    setProperty: function(prop, value, jsonPath) {
        return this.get(jsonPath).then(function(jsonObject) {
//      ^^^^^^
            // Set the property
            jsonObject[prop] = value;
            // Save the file
            return this.save(jsonObject, jsonPath);
//          ^^^^^^
        }.bind(this));
    }
};
发布评论

评论列表(0)

  1. 暂无评论