В чем разница между разрешением (тогда можно указывать) и разрешением (не-потомным объектом)? - PullRequest
0 голосов
/ 22 декабря 2018

Я пытался понять разницу между resolve(thenable) и resolve('non-thenable-object').

. В примерах ниже используйте обещание вместо thenable, потому что обещание также thenable и может быть легче для понимания.

Демо1: resolve(promise)

let resolvePromise = new Promise(resolve => {
  let resolvedPromise = Promise.resolve()
  resolve(resolvedPromise)
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

результат:

  • обещание1
  • обещание2
  • ResolutionPromise разрешено
  • обещание3

Демо-версия: resolve('non-thenable-object')

let resolvePromise = new Promise(resolve => {
  resolve('non-thenable-object')
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

результат:

  • resolPromise разрешено
  • обещание1
  • обещание2
  • обещание3

Итак, я проверил спецификацию и нашел Функции разрешения обещания .Затем добрались до PromiseResolveThenableJob и EnqueueJob .

Итак, согласно спецификации, я думаю, что demo1 было похоже на

Demo3:

let resolvePromise = new Promise(resolve => {
  let resolvedPromise = Promise.resolve()
 // resolve(resolvedPromise)
  // works like 
  Promise.resolve().then(() => {
    Promise.resolve(resolvedPromise).then(() => {
      resolve()
   })
  })
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

Я так думаю, потому что Функции разрешения обещаний говорят:

Выполнить EnqueueJob («PromiseJobs», PromiseResolveThenableJob, «обещание, разрешение, затем действие»).

И PromiseResolveThenableJob говорит:

Это задание использует предоставленное свойство thenable и метод then для разрешения данного обещания. Этот процесс должен выполняться как задание, чтобы гарантировать, что оценка метода then происходит после завершения оценки любого окружающего кода.

Кроме того, я думаю, demo2 работает как

Демо4:

//let resolvePromise = new Promise(resolve => {
  //resolve('str')
//})
//works like
let resolvePromise = Promise.resolve('str')

resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})

resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

Как и Функции разрешения обещания говорит:

Если IsCallable (thenAction) имеет значение false, тогда Return FulfillPromise (обещание, разрешение).

Хотя результаты между Demo1 - Demo3 и Demo2 - Demo4 равныЯ до сих пор не уверен, был ли я прав.Итак, я здесь, чтобы спросить

, правильна ли моя логика?Если нет, как вы объясните различные порядки между resolve(thenable) и resolve(non-thenable)?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

После прочтения спецификации и тестирования много раз я думал, что смогу ее получить.

Прежде чем мы начнем, мы должны что-то уладить.

Давайте назовем это RESOLVE() при использовании resolve в Promise executor.Например, RESOLVE(thenable) означает код, подобный следующему:

  new Promise((resolve,reject)=>{
    resolve(thenable)
  })

, а resolve(thenable) означает Promise.resolve(thenable)

Хорошо, давайте начнем.

Promise.resolve('non-thenable') и RESOLVE('non-thenable')

Когда мы используем Promise.resolve('non-thenable'), речь идет о Promise.resolve

enter image description here

Тогда этоприходит к PromiseResolve

enter image description here

Вот где Promise.resolve('non-thenable') было преобразовано в

new Promise(resolve=>{
  resolve('non-thenable')
})

Итак,у нас есть заключение:

Promise.resolve('non-thenable') можно преобразовать в RESOLVE('non-thenable')


RESOLVE(thenable)

demo1

let resolveThenable = new Promise((resolve, reject) => {
  let thenable = {
    then: function (resolve, reject) {
      console.log('in thenable')
      resolve(42)
    }
  }
  resolve(thenable)
  // works like
  // Promise.resolve().then(() => {
  //   thenable.then(resolve)
  // })
  // should be ?
  // Promise.resolve().then(() => {
  //   thenable.then.[[Value]](resolve)
  // })
  // equivalent to?
  // Promise.resolve().then(() => {
  //   thenable.then(resolve)
  // })
})
resolveThenable.then(() => {
  console.log('resolveThenable resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

// 'in thenable'
// 'promise1'
// 'resolveThenable resolved'
// 'promise2'
// 'promise3'

Согласно функциям разрешения обещаний , когда мы использовали RESOLVE(thenable), речь идет о

enter image description here

Затем дело доходит до PromiseResolveThenableJob

enter image description here

Это позволит RESOLVE(thenable) работать как

  Promise.resolve().then(() => {
    thenable.then.[[Value]](resolve)
  })

Итак, я подумал, что это эквивалентно

  Promise.resolve().then(() => {
    thenable.then(resolve)
  })

, который получил тот же результат, что и RESOLVE(thenable).

Итак, мы можем сказать RESOLVE(thenable) можно преобразовать в

  Promise.resolve().then(() => {
    thenable.then(resolve)
  })
demo2

let resolvePromise = new Promise((resolve, reject) => {
  let resolvedPromise = Promise.resolve()
  resolve(resolvedPromise)
  // works like
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(() => {
  //     resolve()
  //   })
  // })
  // should be?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then.[[Value]](resolve,reject)
  // })
  // equivalent to ?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(resolve)
  // })
  // equivalent to ?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(() => {
  //     resolve()
  //   })
  // })
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

// 'promise1'
// 'promise2'
// 'resolvePromise resolved'
// 'promise3'

Когда мы говорили о RESOLVE(resolvedPromise), мы можем обнаружить, что спецификация не отличает thenable от promise.Таким же образом, RESOLVE(resolvedPromise) может быть преобразован в

  Promise.resolve().then(() => {
    resolvedPromise.then(resolve)
  })

Хотя в этом случае порядок между RESOLVE(thenable) и RESOLVE(promise) отличается.Потому что thenable.then - это операция синхронизации, а resolvedPromise.then - это асинхронная операция.Это не тот же метод then.

Итак, вот наш вывод:

И RESOLVE(thenable), и RESOLVE(promise) можно преобразовать в

 new Promise((resolve, reject) => {
      Promise.resolve().then(() => {
        thenable.then(resolve)
      })
 })

Promise.resolve (затем)

Это довольно просто при использовании Promise.resolve(promise), потому что он возвращает аргумент promise.

Однако при использовании Promise.resolve(thenable) все усложняется, и thenable не является обещанием.Давайте назовем это Promise.resolve(nonPromiseThenable).

Согласно Promise.resolve (x)

enter image description here

Тогда этоприходит к

enter image description here

Таким образом, Promise.resolve(nonPromiseThenable) может быть преобразовано в

 new Promise(resolve => { 
   resolve(nonPromiseThenable)
 })

И, наконец, приходит к

 new Promise(resolve => { 
   Promise.resolve().then(() => { 
     nonPromiseThenable.then(resolve) 
   }) 
 })

Вы можете проверить это в демоверсии ниже.

var thenable = {
  then(resolve, reject) {
    resolve(1)
  }
}
// code transformation 
Promise.resolve(thenable).then(res => {
  console.log(res)
})
// equal 
// new Promise(resolve => { 
//   resolve(thenable) 
// }).then(res => { 
//   console.log(res) 
// }) 
// equal 
// new Promise(resolve => { 
//   Promise.resolve().then(() => { 
//     thenable.then(resolve) 
//   }) 
// }).then(res => { 
//   console.log(res) 
// }) 

new Promise(resolve => resolve(2))
  .then(res => {
    console.log(res)
  })
  .then(res => console.log(3))

В конце давайте сделаем вывод:

  • Promise.resolve('nonThenable') можно преобразовать в RESOLVE('nonThenable').Они имеют одинаковые эффекты.
  • Promise.resolve(thenable) отличается от RESOLVE(thenable).Они имеют разные эффекты.
  • RESOLVE(thenable) и RESOLVE(promise) могут быть преобразованы в new Promise((resolve, reject) => { Promise.resolve().then(() => { thenable.then(resolve) }) })
  • Promise.resolve(promise) === promise, в то время как Promise.resolve(nonPromiseThenable) могут быть преобразованы в new Promise(resolve => { Promise.resolve().then(() => { nonPromiseThenable.then(resolve) }) })
0 голосов
/ 22 декабря 2018

Да, ваша логика выглядит правильно.

new Promise(resolve => resolve('non-thenable-object')) эквивалентно Promise.resolve('non-thenable-object') для всех целей.

В вашей демонстрационной версии 3, однако, я бы рекомендовал опустить Promise.resolve(resolvedPromise).Я не уверен, было ли это намеренно или нет, но Promise.resolve имеет ярлык, когда его аргумент уже является обещанием, и затем возвращает resolvedPromise как есть.Вы бы лучше написать

new Promise((resolve, reject) => {
  let resolvedPromise = Promise.resolve();
  // resolve(resolvedPromise) works like 
  Promise.resolve().then(() => resolvedPromise.then(resolve, reject));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...