【发布时间】:2015-09-08 15:02:18
【问题描述】:
我已经看到可以直接调用本机 ES6 Promise.resolve() - 作为静态方法。 Facebook 在他们的 Flux 示例中就是这样使用它的。
但在什么情况下我应该这样做?排队?还是不使用window.setTimeout()?
【问题讨论】:
我已经看到可以直接调用本机 ES6 Promise.resolve() - 作为静态方法。 Facebook 在他们的 Flux 示例中就是这样使用它的。
但在什么情况下我应该这样做?排队?还是不使用window.setTimeout()?
【问题讨论】:
当您需要创建已解决的承诺时,您应该调用Promise.resolve(object)。例如,您可能有一个函数开始从服务器下载资源或返回其缓存版本:
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
});
}
}
【讨论】:
then()?
then() 调用的回调不一定会“很快”(下一个周期..)被调用,并且可能需要无限量的时间取决于在 resolve 电话中发布的内容。
Promise.resolve(42) 只是一个简写形式
new Promise(function(resolve) {
resolve(42);
});
因此,每当您发现自己在做这样的事情时,即从现有值创建承诺时,您都可以改用 Promise.resolve。
【讨论】:
从语义上讲,返回 Promise 的函数是异步函数,并且如您所知,可以链接在一起:
a().then(b).then(c).catch(failure);
虽然同步函数也可以是异步链的一部分,但这只是因为.then 函数会自动将您传递给它的函数的返回值提升为 Promise。例如。如果b 和/或c 返回的值不是承诺,那么链仍然有效,但如果a 返回一个非承诺值,那就是TypeError。
在大多数情况下你可能知道a返回什么,所以这很好,但如果你不知道a 会返回什么(比如你正在做泛型编程),那么你可以这样做:
Promise.resolve(a()).then(b).then(c).catch(failure);
a、b 和 c 现在在这方面被同等对待:
a 返回1,那么b 将很快被1 调用。a 返回一个承诺,那么b 将被链接在a 后面。Promise.reject 方法对故障链完成同样的事情。
此外,在您只需要立即解决的承诺的情况下,这些方法会很方便。例如
[a, b, c].reduce((p, f) => p.then(f), Promise.resolve()).catch(failure);
【讨论】:
Promise.resolve().then(a)…。
a 确实是新序列中的第一个方法并且它有一个同步组件,那么可能需要确保它的同步部分在一个返回之前已经运行(大多数浏览器 API 至少努力同步进行输入验证通过检查承诺状态和原因使它们在 js 调试器中可观察),或者只是为了避免额外的调度。但如果a、b 和c 是真的等于,那么您的建议可能更可取。