Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

Promise的脱衣秀

  Promise中有个特性,任何传给resolve的参数都会被脱个精光!什么意思呢?我们可以在resolve的使用传一般的值,它会被传到then上,但要是在resolve中传入另一个Promise呢?那么当前这个调用了resolve的Promise不会立即完成,而是等待传入的Promise被解决。
  先放一个比较直观的例子
<script>
//首先我们有一个这样的promise
var p1=new Promise(function(resolve){
  setTimeout(function(){
    resolve("ok");
  },2000);
});
//然后又有一个这样的
var p2=new Promise(function(resolve){
  setTimeout(function(){
    resolve(p1);
  },1000);
});
//之后还可能有一个这样的
var p3=new Promise(function(resolve){
  //虽然这个resolve是被即时调用的
  //但实际上调用完后这个promise任然在等待状态
  //因为其传入的参数也是一个promise
  resolve(p2);
});
//控制台可以看到此时它已经是resolve状态了
//但实际上它的then现在并没有被执行
console.log(p3);
p3.then(function(e){
  //通过从then的回调参数中传回来的值永远不可能是promise对象
  //因为resolve执行后会处理所有嵌套的promise对象
  console.log(e);
});
</script>
  也就是说,p3resolve(p2),传入的参数被一层层脱掉Promise包装,所以最终我们得到的是p1中产生的字符串值 "ok",至此才停止脱衣。是不是一场很精彩的脱衣秀呢?实际上,这个嵌套可以很深很深,比如我们用一个递归来生成
<script>
//这个代码是可以正常工作的,直接脱掉1000层promise包装
var depth=1E3;
(function callee(){
  if(--depth==0)return Promise.resolve("ok");
  return new Promise(function(resolve){
    resolve(callee());
  });
})().then(function(e){
  console.log(e);
});
</script>
  但是,上面这段代码的深度如果改成1E4,并且运行时控制台是开启状态的话会导致Chrome38奔溃。

  不过这不是重点,正常不会有哪个逗比会用这么深的Promise嵌套。我只是觉得这个脱衣机制是个很精彩的东西,也许可以在更多地方利用上。嘛,具体还有待研究,现在就这样吧。
  另外,Chrome崩溃的这个囧脸挺萌的!哈哈哈!!
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^