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
565 views
in Technique[技术] by (71.8m points)

asynchronous - Getting synchronous behavior in javascript?

While developing a mobile PhoneGap app I had an interesting problem. I needed to query about 10 items of data from the database (through PhoneGaps SQLite API)... Like many javascript API's, this one was asynchronous. When you made your query, you would pass in a "success" handler.

Now, my preference in this case would have been a synchronous query method that returned only when complete. Then I could have written straight line code that queried each of the 10 items 1 after another.

Because of the asynchronous nature of PhoneGap (really, I see this all over JS however) I was forced to write a beast that looked like this:

db.query( "SELECT...", success() {
    db.query( "SELECT...", success() {
        db.query( "SELECT...", success() {
            db.query( "SELECT...", success() {
                db.query( "SELECT...", success() {
                }
            }
        }
    }
}

And this is only half as deep as I had to go (and greatly simplified...)... When, had I been using SQLite in C, I could have simply done something like:

db.query( "SELECT...", resultA );
db.query( "SELECT...", resultB );
db.query( "SELECT...", resultC );
db.query( "SELECT...", resultD );
db.query( "SELECT...", resultE );

It seems to me that the success handler approach is great when you only have to go 1 or 2 levels deep... But, completely falls apart when you need more than that...

Is their a library, or feature of a library somewhere that makes this easier?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

This is a problem that is so prevalent in the community that many patterns and libraries have arisen to combat it.

My favorite is promises. I gave a presentation on promises as a solution to the async problem at a few events; you can check out my slides on SlideShare: Callbacks, Promises, and Coroutines (oh my!): The Evolution of Asynchronicity in JavaScript. It also explains why asynchronicity is necessary---in short, because JavaScript is single-threaded.

For the particular example you give, check out slide 53 and thereabouts. In brief, assuming db.query returned a promise, it would look like:

db.query("SELECT...")
  .then(function (a) {
    return db.query("SELECT..." + a);
  })
  .then(function (b) {
    return db.query("SELECT..." + b);
  })
  .then(function (c) {
    return db.query("SELECT..." + c);
  })
  .then(function (d) {
    return db.query("SELECT..." + d);
  })
  .then(function (e) {
    return db.query("SELECT..." + e);
  });

Of course it becomes a lot nicer if you don't need to use the results of one query for the next:

Q.all([
  db.query("SELECT..."),
  db.query("SELECT..."),
  db.query("SELECT..."),
  db.query("SELECT..."),
  db.query("SELECT...")
]).spread(function (a, b, c, d, e) {
  // ...
});

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

...