When should I call Promise.resolve() directly?

2020-08-21 03:14发布

问题:

I've seen that the native ES6 Promise.resolve() can be invoked directly - as a static method. Facebook is using it that way in their Flux examples.

But in what case should I do that? To queue something? Or instead of using window.setTimeout()?

回答1:

You should call Promise.resolve(object) when you need to create a promise that is already resolved. For example you may have a function that starts downloading a resource from the server or returns its cached version:

function getImage(imageUrl) {
    if (imageUrl in this.cache) {
        // no need to download, return immediately
        return Promise.resolve(this.cache[imageUrl]);
    } else {
        return new Promise(function(resolve, reject) {
            // start downloading and eventually resolve
        });
    }
}


回答2:

Promise.resolve(42) is just a shorthand for

new Promise(function(resolve) {
    resolve(42);
});

So whenever you find yourself doing something like this, i.e. creating a promise from an existing value, you can use Promise.resolve instead.



回答3:

Semantically, functions that return promises are asynchronous functions, and, as you know, can be chained together:

a().then(b).then(c).catch(failure);

While synchronous functions can be part of asynchronous chains as well, this only works because the .then function automatically promotes return values from the functions you pass it, to promises. E.g. If b and/or c return values that are not promises, then the chain still works, but if a returns a non-promise value then that's TypeError.

In most cases you probably know what areturns, so this is fine, but in cases where you don't know what a will return (say you're doing generic programming), then you can do this:

Promise.resolve(a()).then(b).then(c).catch(failure);

a, b and c are now treated the same in this regard:

  • If a returns 1, then b will be called soon with 1.
  • If a returns a promise, then b will be chained behind a.

The method Promise.reject accomplishes the same thing for failure chains.

Additonally, these methods can be handy in cases where you just need a promise that resolves right away. E.g.

[a, b, c].reduce((p, f) => p.then(f), Promise.resolve()).catch(failure);