Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
677 views
in Technique[技术] by (71.8m points)

asynchronous - chaining async method calls - javascript

You have a prototype object Foo with two async method calls, bar and baz.

var bob = new Foo()

Foo.prototype.bar = function land(callback) {
  setTimeout(function() {
    callback()
    console.log('bar');
  }, 3000);
};

Foo.prototype.baz = function land(callback) {
  setTimeout(function() {
    callback()
    console.log('baz');
  }, 3000);
};

We want to do bob.bar().baz() and have it log "bar" and "baz" sequentially.

If you cannot modify the method calls (including passing in your callback function), how can you pass a default callback into these method calls?

Some ideas:

  1. Wrap "bob" with decorator (still fuzzy on how to implement, could use a small example)

  2. Modify constructor to assign default callback if none assigned (have not considered if this is possible or not)

  3. Use a generator wrapper that will continue to call next method until none are left?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The more recommended way instead is to use promises as this is the community-wide practice to do async work.

We want to do bob.bar().baz() and have it log "bar" and "baz" sequentially.

Why would you want to do that just to achieve this bob.bar().baz() "syntax"? You could do it pretty neatly using the Promise API w/o additional efforts to make that syntax work that indeed increases code complexity reducing the actual readability.

So, you might want to consider using the promise-based approach like this. It offers much flexibility than what you would have achieved with your approach:

Foo.prototype.bar = function () {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve()
            console.log('bar');
        }, 3000);
    };
};

Foo.prototype.baz = function () {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve()
            console.log('baz');
        }, 3000);
    };
};

Now you'd do this to run them sequentially one after another:

var bob = new Foo();

bob.bar().then(function() {
   return bob.baz();
});

// If you're using ES2015+ you could even do:
bob.bar().then(() => bob.baz());

If you need to chain more functions you could simply do it:

bob.bar()
    .then(() => bob.baz())
    .then(() => bob.anotherBaz())
    .then(() => bob.somethingElse());  

Anyway, if you're not used to using promises you might want to read this


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...