JavaScript 承诺如何在幕后工作 [英] How JavaScript promises work behind the scenes

查看:16
本文介绍了JavaScript 承诺如何在幕后工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当 promise 被生产和消费时,我对幕后发生的事情感到非常困惑.请澄清我的观点,并为我的英语能力不佳而道歉.

I'm so much confused about what happens behind the scenes when promise is produced and consume. Please clarify my points and sorry for my weak English.

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

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

What happens next ? When then method is called the code of then method goes to background? I imagine it goes to background and a variable is console.log // 10

主代码执行完成后,异步代码开始setTimeout回调开始执行,执行完成后promise完成,resolved函数返回值.这个值是如何存储在 promise 对象中的,在 then 方法中会发生什么?

After main code execution finishes, async code start setTimeout callback begins to execute and after execution finishes promise is fulfilled and resolved function returns value. How is this value stored in promise object and what happens in then method ?

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)

推荐答案

以下是内置Promise 类.catchfinally 尚未实现.

The following is a simplified implementation of the built-in Promise class. catch and finally have not been implemented.

提供给 Promise 构造函数的函数称为 executor 函数,会立即同步调用.

The function supplied to the Promise constructor is called the executor function, and is invoked immediately and synchronously.

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

Every promise has a method .then, enabling the chaining of promises.

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

Functions supplied to .then are always invoked asynchronously on a microtask (note use of queueMicrotask below).

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

Every time .then is called, a new promise is created and returned.

.then 可以在同一个承诺上多次调用,创建承诺结果的多播,以及承诺链的分支.

.then can be called more than once on the same promise, creating a multicast of the result of the promise, and a branching of the promise chain.

promise 可以处于以下三种状态之一:pending、fulfiled 或 denied.状态转换是单向的:您不能从已完成或已拒绝,再回到待处理状态.

A promise can be in one of three states: pending, fulfilled, or rejected. State transitions are unidirectional: you cannot move from fulfilled or rejected, back to pending.

如果一个 Promise 被另一个 Promise 解决,那么两个 Promise 链就会连接起来,并且外部 Promise 具有内部 Promise 的状态(可能是待处理的),直到内部 Promise 解决.

If a promise is resolved with another promise, then the two promise chains are joined and the outer promise takes on the status of the inner promise (which could be pending), until the inner promise resolves.

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)

请参阅另见.

这篇关于JavaScript 承诺如何在幕后工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆