V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
1heart
V2EX  ›  分享创造

深入 Promise(二)——进击的 Promise

  •  
  •   1heart · 2017-02-14 18:14:21 +08:00 · 2116 次点击
    这是一个创建于 2618 天前的主题,其中的信息可能已经有所发展或是发生改变。

    twitter 上有一道关于 Promise 的题,执行顺序是怎样?见下图: 1

    我们假设 doSomething 耗时 1s , doSomethingElse 耗时 1.5s :

    function doSomething() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('something')
        }, 1000)
      })
    }
    
    function doSomethingElse() {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('somethingElse')
        }, 1500)
      })
    }
    
    1. 第一种情况:
    console.time('case 1')
    doSomething().then(() => {
      return doSomethingElse()
    }).then(function finalHandler(res) {
      console.log(res)
      console.timeEnd('case 1')
    })
    

    打印出:

    somethingElse
    case 1: 2509ms
    

    执行顺序为:

    doSomething()
    |----------|
               doSomethingElse()
               |---------------|
                               finalHandler(somethingElse)
                               |->
    

    解释:正常的 Promise 用法。

    1. 第二种情况:
    console.time('case 2')
    doSomething().then(function () {
      doSomethingElse()
    }).then(function finalHandler(res) {
      console.log(res)
      console.timeEnd('case 2')
    })
    

    打印出:

    undefined
    case 2: 1009ms
    

    执行顺序为:

    doSomething()
    |----------|
               doSomethingElse()
               |---------------|
               finalHandler(undefined)
               |->
    

    解释:因为没有使用 return , doSomethingElse 在 doSomething 执行完后异步执行的。

    1. 第三种情况:
    console.time('case 3')
    doSomething().then(doSomethingElse())
      .then(function finalHandler(res) {
        console.log(res)
        console.timeEnd('case 3')
      })
    

    打印出:

    something
    case 3: 1008ms
    

    执行顺序为:

    doSomething()
    |----------|
    doSomethingElse()
    |---------------|
    
           finalHandler(something)
           |->
    

    解释:上面代码相当于:

    console.time('case 3')
    var doSomethingPromise = doSomething()
    var doSomethingElsePromise = doSomethingElse()
    doSomethingPromise.then(doSomethingElsePromise)
      .then(function finalHandler(res) {
        console.log(res)
        console.timeEnd('case 3')
      })
    

    而我们知道 then 需要接受一个函数,否则会值穿透,所以打印 something 。

    1. 第四种情况:
    console.time('case 4')
    doSomething().then(doSomethingElse)
      .then(function finalHandler(res) {
        console.log(res)
        console.timeEnd('case 4')
      })
    

    打印出:

    somethingElse
    case 4: 2513ms
    

    执行顺序为:

    doSomething()
    |----------|
               doSomethingElse(something)
               |---------------|
                               finalHandler(somethingElse)
                               |->
    

    解释: doSomethingElse 作为 then 参数传入不会发生值穿透,并返回一个 promise ,所以会顺序执行。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3161 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:30 · PVG 22:30 · LAX 07:30 · JFK 10:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.