Should We Be Using Promises in Async PHP?
I’d like to talk briefly about a new survey that I’m trying to distribute. It’s nothing amazing, just a really short poll to try and help me gage people’s opinions using Promises for handling asynchronous code. Let me explain why this survey is important.
I am currently working on an architectural redesign for Evflow, an experiment in asynchronous code with PHP. I started the project mid-2014 and a lot has changed since then. PHP 5.6 was released in August 2014, and PHP 7 is in alpha and comes with it a host of new features and improvements. Evflow’s current architecture is a bit flimsy and mostly consists of random ideas glued together.
We need promises!
I’d love to talk your ear off about all the exciting, cool new things I have in the works for Evflow (including a better name!), but that is not the subject of this post. Instead, let’s consider promises for a moment. For those of you who don’t know what a “promise” is, it is like an alternative to callbacks for delayed functions. I’d recommend reading an article such as this one to get up to speed.
Promises have taken the JavaScript world by storm, but what does this have to do with PHP? Well, JavaScript needs something like promises to avoid callback hell, since a large number of things in JavaScript are already asynchronous. If we want to create asynchronous systems in PHP, which me and others as well are convinced of doing, it would be prudent to learn from the mistakes of other languages and get it right the first time. Consider the following code:
$asyncFS = new CoolAsyncFileSystemImpl();
$asyncFS->fileGetContents('query.sql', function($contents) {
AsyncDB::query($contents, function($result) {
$asyncFS->fileGetContents('http://example.com?x='.$result['x'], function($response) {
echo $response;
});
});
});
This contrived example demonstrates this “callback hell” that we are trying to avoid. Promises, on the other hand, avoid this to some extent (not that you can’t write bad code with promises). Here is the above code rewritten to use promises:
$asyncFS = new CoolAsyncFileSystemImpl();
$asyncFS->fileGetContents('query.sql')
->then(function($contents) {
return AsyncDB::query($contents);
})->then(function($result) {
return $asyncFS->fileGetContents('http://example.com?x='.$result['x']);
})->then(function($response) {
echo $response;
});
Much cleaner, don’t you think? This is why promises are so popular and projects like ReactPHP use them as their callback mechanism of choice.
We need promises… or do we?
But are promises really the answer? With things like generators and coroutines, some have suggested that typical promises aren’t the best solution for PHP. I haven’t decided myself, so I decided to create this survey to see what you as the community thinks. You can click the link below to take the survey:
I will analyze the survey results and post my response here when the survey ends, which will be in one week from now, on July 1. Feel free to let me know what you think in the comments below.
Update: I have analyzed and discussed the survey results and posted them here, but the survey is still open if you’d like to take it.
3 comments
Let me know what you think in the comments below. Remember to keep it civil!
Subscribe to this thread
I think promises of some form are required to create coroutines for async programming. Solutions with promises that do not conform to the Promises/A+ spec are still fundamentally promises, just implemented in a different way.
I use promises in Icicle to implement coroutines. Promises in Icicle include a
done()
method that does not return another promise, only registers callbacks. This method is used by coroutines to avoid creating unnecessary promises, making the implementation very performant. Using promises in this way eliminates most of the performance penalties when using promises in a coroutine, yet allows the coder to combine or use promises directly if desired.I noticed they survey included a question about a Promises PSR. I am working on such a proposal. I’ve created a repo at https://github.com/thenable/thenable that will be the basis of the proposal.
I agree that some form of promises are necessary, when you consider futures/awaitables/tasks some form of promises. That’s an excellent point. I guess really the debate is, should we follow the Promises/A+ spec? I don’t have anything against it, but I’m not 100% convinced. Maybe I’m just too API-picky.
That’s awesome! I wasn’t confident in doing one myself since I’m not sure about the API, but I would definitely support someone else’s. I’d love to help with it as well, if you need any. 😃
It’s just syntactic shugar. If you replace the “echo $responce;” with “echo ‘hello world’;” And than NOT execute all the stuff before. Than it would be as awesome.
Just like: ->then(function($str) { return strtolower($str) })->then(function($str) { return strtoupper($str) })->then(function($str) { return strtolower($str) })
Would be: ->then(function($str) { return strtolower($str) })
So looks nice, but doesn’t behave like a monad.