JavaScript Promise 如何在幕后工作

jav*_*ver 5 javascript promise es6-promise

当承诺产生和消耗时,我对幕后发生的事情感到非常困惑。请澄清我的观点,并对我的英语不好表示歉意。

  1. 使用 new 关键字创建空白对象 Promise 构造函数被调用,并且 new 关键字设置 Promise 构造函数的 this 指向空白对象 this = Blankobject。
  2. Promise 构造函数接收参数中的回调(执行器函数)并调用执行器函数。
  3. 执行器函数接收两个回调(resolve、reject)作为参数
  4. setTimeout 在执行器函数中被调用,setTimeOut 是异步代码
  5. 异步代码进入后台,然后 Promise 构造函数返回以前为空白对象的 Promise 对象,并将 Promise 对象引用保存到 myPromise。
  6. 创建了一个变量

接下来发生什么 ?当then方法被调用时,方法的代码then会转到后台吗?我想它会进入后台,变量是 console.log // 10

主代码执行完成后,异步代码启动setTimeout回调开始执行,执行完成后,promise 得到满足,resolved 函数返回值。这个值如何存储在 Promise 对象中以及then方法中发生了什么?

let myPromise = new Promise (
    (resolve, reject) => {

        setTimeout(() => {
            console.log(getIDs)
            resolve(10);

        }, 1500);

    }
)


let a = 10
        myPromise.then(val => {
            console.log(val);

        })
        console.log(a)
Run Code Online (Sandbox Code Playgroud)

Ben*_*Ben 8

以下是内置Promise 类的简化实现。catchfinally没有得到实施。

提供给 Promise 构造函数的函数称为执行器函数,并且会立即同步调用。

每个 Promise 都有一个方法.then,可以实现 Promise 的链接。

提供给的函数.then 始终在微任务上异步调用(请注意queueMicrotask下面的使用)。

每次.then调用时,都会创建并返回一个新的 Promise。

.then可以对同一个 Promise 多次调用,创建 Promise 结果的多播以及 Promise 链的分支。

承诺可以处于三种状态之一:待定、已履行或已拒绝。状态转换是单向的:您无法从已完成或已拒绝返回到待处理。

如果一个 Promise 通过另一个 Promise 得到解决,那么两个 Promise 链就会连接在一起,并且外部 Promise 呈现内部 Promise 的状态(可能处于待处理状态),直到内部 Promise 得到解决。

function Promise(executor) {
  if (!executor) throw "Promise executor undefined"
  let status = "pending", value, thenQ = []

  const then = onFulfilled => {
    let resolver
    // This ensures control does not move to later promises 
    // until prior promises have been resolved.
    const nextPromise = new Promise(resolve => (resolver = resolve))
    // More than one "then" can be registered with each promise.
    thenQ.push((...args) => resolver(onFulfilled(...args)))
    return nextPromise
  }

  // We check if the result is a "thenable"; if so, we treat
  // it as an inner promise, otherwise we simply fulfil with 
  // the result.
  const resolve = result => result?.then ? result.then(fulfil) : fulfil(result)

  // When a promise has been fulfilled, its "thens" can be run.
  const fulfil = result => (status = "fulfilled", value = result, executeThens(value))

  // "Thens" are run asynchronously, on a microtask.
  const executeThens = value => queueMicrotask(() => thenQ.forEach(el => el(value)))

  // The executor is run synchronously.
  executor(resolve)

  return {
    then,
    get status() { return status },
    get value() { return value }
  }
}

// Chaining
new Promise(resolve => {
  console.log('Waiting for step 1...')
  setTimeout(() => resolve("One, two..."), 1500)
})
.then(result => new Promise(resolve => {
  console.log('Waiting for step 2...')
  setTimeout(() => resolve(`${result}three, four`), 1500)
}))
.then(result => console.log(`Chaining result: ${result}.`))

// Branching
const p = new Promise(resolve => {
  console.log('Waiting for step a...')
  setTimeout(() => resolve("Alpha, Bravo..."), 1500)
})

p.then(result => new Promise(resolve => {
  console.log('Waiting for step b1...')
  setTimeout(() => resolve(`${result}Charlie, Delta`), 1500)
})).then(console.log)

p.then(result => {
  console.log('Waiting for step b2...')
  return `${result}Echo, Foxtrot`
}).then(console.log)
Run Code Online (Sandbox Code Playgroud)

也可以看看。