As for the back button, yeah, I need to add routing: https://github.com/nolanlawson/pokedex.org/issues/2
1,091 karma · joined August 13, 2013
As for the back button, yeah, I need to add routing: https://github.com/nolanlawson/pokedex.org/issues/2
Also I don't believe you can use the SQLite Plugin in a web worker either: https://github.com/litehelpers/Cordova-sqlite-storage/issues...
Luckily, you can still access IndexedDB from a web worker on both platforms (if you are able to use Safari's partial implementation). Also depending on what kind of work you're doing in the database, most of the action happens at the native level rather than the (DOM-blocking) JS level.
What bothered me most about the IndexedDB fiasco with iOS8 is that Apple not only held out for so many years, but then they deployed a broken implementation. Anybody who had written an app using an IndexedDB shim either had a crashed site at best or lost user data at worst. YDN-DB author Kyaw Tun had the best quote: "I don't understand how they can release this."
Whether you like an API or not, a browser vendor should at least release it in good faith if they're going to release it.
The problem is that when everybody wants to discuss the hot new browser features, mentioning Apple is just a big downer. We all know we're going to have to polyfill at best, or just not support Safari at worst. Nobody wants to be reminded of that sad fact when you're trying to get excited about the potential of the web platform.
And yeah, the title is pretty clickbaity; guilty as charged! But my blog has no ads, so it's not like I'm making money off of it. I'm just trying to draw attention to what I think is an important issue.
As others have pointed out, it's all a matter of perspective. If you're trying to build for Web 2.0, then Safari is a fine browser. But if you're trying to build for Web 3.0 (or the "next web" or "appy web" or whatever you want to call it), then prepare to be disappointed.
So if you're ever trying to debug promises in a non-Chrome browser, you may find my "insane" advice pretty helpful. :)
Anyway, the big benefit of async/await, to me, is that you really DON'T have to understand promises. :) For instance, at some point we will probably add ES7 examples to the PouchDB API docs (e.g. here: http://pouchdb.com/api.html#create_document), and you can imagine that, from the user's perspective, the word "await" will just be part of the API (e.g. `var doc = await db.get('id')`), and beyond that, they won't have to learn anything about promises or async or callbacks or any of that.
That's exactly what I meant when I said it's better for your tools to warn you, rather than trying to read and understand some lengthy article. :)
BTW for PouchDB, we use bluebird in Node and lie in the browser, and bluebird has been truly indispensable for debugging. Looking forward to it getting even better!
doSomething(function (err) {
doSomethingElse(function (err) {
doYetAnotherThing(function (err) {
throw new Error(
"I don't bubble up to the top of the stack, " +
"because there is no stack!");
});
});
});
BTW a great trick is to tick the little "Async" box in the Chrome Dev Tools, so you can get a full stacktrace showing exactly where you came from. It works for both callbacks and promises: http://www.html5rocks.com/en/tutorials/developertools/async-...In that "Promise protips" gist (https://gist.github.com/nolanlawson/6ce81186421d2fa109a4), I have an example of something closer to what you describe: the sequentialize() function will execute one promise after the other, and fail as soon as a single one fails.
However, if you need to actually run multiple promises in parallel, but cancel them as soon as a single one fails, then you might want something more advanced than promises, like RactiveJS (https://github.com/ractivejs/ractive) or RxJS (https://github.com/Reactive-Extensions/RxJS).
naivePromiseAPI() {
if (foo) {
throw new Error('this will get swallowed!');
}
return somePromise();
}
Instead you want this: cleverPromiseAPI() {
return Promise.resolve().then(function () {
if (foo) {
throw new Error('this won't get swallowed!');
}
return somePromise();
});
}
Because if the client of the API does something like this: $('.my-button').on('click', function () {
cleverPromiseAPI().catch(console.log.bind(console));
});
Then the client might expect the error to get console.logged, but actually it won't in the naive case. That's because the error was thrown synchronously and thus bubbled up to the click handler, instead of being caught inside of the promise chain.The only reason I didn't include something like that in the post is that I didn't want to overwhelm newbies. I think it's already confusing enough what the difference is between q/when/RSVP/bluebird/jQuery promises/Angular promises, etc... And honestly, more and more I just use vanilla promises, or a tiny polyfill like Lie.
Since CoffeeScript and Handlebars are written in Jison, you'd think someone would have done this already, but I couldn't wrap my head around the Ace highlighter implementation for those languages. It didn't seem to be as simple as "plug in this Jison grammar and get a highlighter." If that were the case, it would be easy, because Jison itself is written in Jison. :)
And in practice, I don't think it will be that hard to explain to newbie programmers. Most of them will not be writing code that actually produces promises, just the code that consumes it (because they're not writing ajax/database libraries). So the "await" basically becomes part of the library API from their perspective.
E.g. they type "await library.doSomething()", their editor tells them that the surrounding function needs to be async, so they add the word "async," and they're done. They don't have to learn a completely new system in order to work with this library.
As for the uncaught Promise rejection project, it is certainly nasty (and has burned me many times as I worked on Pouch), but I'm hoping this can be solved by better tools. E.g. in Chrome, they recently started logging uncaught promise rejections to the console.
For instance, the following three blocks are not equivalent, but they're easy to mix up:
// executes serially
promise.then(function () {
return somethingThatReturnsAPromise();
}).then(...)
// doesn't wait for something() to return
promise.then(function () {
somethingThatReturnsAPromise();
}).then(...)
// executes something() immediately
promise.then(somethingThatReturnsAPromise()).then(...)
With synchronous code, it's obvious what order things happen in, because you just read top to bottom. But yeah, I do agree that arrow functions make it a bit nicer. :)Those yellows are really more yellow than green, in my experience. :/
I just think it's nice to give a little credit where credit is due. :) I do see that you mention LocalForage in the changelog, but a shout-out on the site would be cool as well.
For my own part, PouchDB is pretty heavily based on LevelUP (in Node.js anyway), so we're sure to document it on the website: http://pouchdb.com/adapters.html#pouchdb_in_node_js
Too many projects have poor documentation/tests, or they don't make it clear how to contribute. Something as simple as a CONTRIBUTING.md file can be really valuable; IRC and mailing lists are also good resources to offer.
[1]: https://github.com/Irrelon/ForerunnerDB/blob/master/package....
Also, Drupal recently announced that they're going to offer a CouchDB-compatible server. So yeah, anybody can implement the sync protocol. :) http://wearepropeople.com/blog/a-content-staging-solution-fo...