gpt4 book ai didi

javascript - 在 JavaScript ES6 中,thenable 的接受如何解决和拒绝?

转载 作者:行者123 更新时间:2023-12-01 17:19:15 24 4
gpt4 key购买 nike

我认为到目前为止我采取的一个原则是:

A promise is a thenable object, and so it takes the message then, or in other words, some code can invoke the then method on this object, which is part of the interface, with a fulfillment handler, which is "the next step to take", and a rejection handler, which is "the next step to take if it didn't work out." It is usually good to return a new promise in the fulfillment handler, so that other code can "chain" on it, which is saying, "I will also tell you the next step of action, and the next step of action if you fail, so call one of them when you are done."



然而,在 a JavaScript.info Promise blog page ,它说履行处理程序可以返回任何“thenable”对象(这意味着类似promise的对象),但是这个thenable对象的接口(interface)是
.then(resolve, reject) 

这与通常的代码不同,因为如果一个履行处理程序返回一个新的 promise ,这个 thenable 对象具有接口(interface)
.then(fulfillmentHandler, rejectionHandler)

所以该页面上的代码实际上得到了 resolve并调用 resolve(someValue) .如果 fulfillmentHandler不只是 resolve 的另一个名称,那么为什么这个 thenable 不同呢?

该页面上的thenable代码:

class Thenable {
constructor(num) {
this.num = num;
}
then(resolve, reject) {
alert(resolve); // function() { native code }
// resolve with this.num*2 after the 1 second
setTimeout(() => resolve(this.num * 2), 1000); // (**)
}
}

new Promise(resolve => resolve(1))
.then(result => {
return new Thenable(result); // (*)
})
.then(alert); // shows 2 after 1000ms

最佳答案

thenable 是包含标识符为 then 的方法的任何对象。
下面是可以写的最简单的thenable。当给 Promise.resolve调用时,一个 thenable 对象被强制转换为一个待处理的 Promise 对象:

const thenable = {
then() {}, // then does nothing, returns undefined
};

const p = Promise.resolve(thenable);

console.log(p); // Promise { <pending> }

p.then((value) => {
console.log(value); // will never run
}).catch((reason) => {
console.log(reason); // will never run
});
编写 thenable 的目的是让它获得 被迫 promise 在我们的代码中的某个时刻。但是一个永远不会解决的 promise 是没有用的。上面的示例具有与以下类似的结果:
const p = new Promise(() => {}); //executor does nothing, returns undefined

console.log({ p }); // Promise { <pending> }

p.then((value) => {
console.log(value); // will never run
}).catch((reason) => {
console.log(reason); // will never run
});
当将其强制为 promise 时,JavaScript 将 thenable 的 then 方法视为 Promise 构造函数中的执行程序(尽管从我在 Node 中的测试来看,JS 似乎为执行程序在堆栈上推送了一个新任务,而对于 thenable 的 then 它会将一个微任务)。
thenable 的 then 方法不等同于 promise 的 then 方法,即 Promise.prototype.then . Promise.prototype.then是一种内置方法。因此它已经实现了,我们只是调用它,传递一两个回调函数作为参数:
// Let's write some callback functions...
const onFulfilled = (value) => {
// our code
};
const onRejected = (reason) => {
// our code
};

Promise.resolve(5).then(onFulfilled, onRejected); // ... and pass both to a call to then
另一方面,Promise 构造函数的 executor 回调参数不是内置的。我们必须自己实现它:
// Let's write an executor function...
const executor = (resolve, reject) => {
// our asynchronous code with calls to callbacks resolve and/or reject
};
const p = new Promise(executor); // ... and pass it to a Promise constructor
/*
The constructor will create a new pending promise,
call our executor passing the new promise's built-in resolve & reject functions
as first and second parameters, then return the promise.

Whenever the code inside our executor runs (asynchronously if we'd like), it'll have
said promise's resolve & reject methods at its disposal,
in order to communicate that they must respectivelly resolve or reject.
*/
一个有用的thenable
现在对于一个实际做某事的thenable。在本例中, Promise.resolve 将 thenable 强制为 promise :
const usefulThenable = {
// then method written just like an executor, which will run when the thenable is
// coerced into a promise
then(resolve, reject) {
setTimeout(() => {
const grade = Math.floor(Math.random() * 11)
resolve(`You got a ${grade}`)
}, 1000)
},
}

// Promise.resolve coerces the thenable into a promise
let p = Promise.resolve(usefulThenable)

// DO NOT CONFUSE the then() call below with the thenable's then.
// We NEVER call a thenable's then. Also p is not a thenable, anyway. It's a promise.
p.then(() => {
console.log(p) // Promise { 'You got a 9' }
})
console.log(p) // Promise { <pending> }
同样, await运营商还 将 thenable 强制为 promise
console.log('global code has control')

const usefulThenable = {
// then() will be enqueued as a microtask when the thenable is coerced
// into a promise
then(resolve, reject) {
console.log("MICROTASK: usefulThenable's then has control")
setTimeout(() => {
console.log('TASK: timeout handler has control')
const grade = Math.floor(Math.random() * 11)
resolve(`You got a ${grade}`)
}, 1000)
},
}

// Immediately Invoked Function Expression
let p = (async () => {
console.log('async function has control')
const result = await usefulThenable //coerces the thenable into a promise
console.log('async function has control again')
console.log(`async function returning '${result}' implicitly wrapped in a Promise.resolve() call`)
return result
})()

console.log('global code has control again')

console.log({ p }) // Promise { <pending> }

p.then(() => {
console.log('MICROTASK:', { p }) // Promise { 'You got a 10' }
})

console.log('global code completed execution')
输出:
/*
global code has control
async function has control
global code has control again
{ p: Promise { <pending> } }
global code completed execution
MICROTASK: usefulThenable's then has control
TASK: timeout handler has control
async function has control again
async function returning 'You got a 10' implicitly wrapped in a Promise.resolve() call
MICROTASK: { p: Promise { 'You got a 10' } }
*/
TL;DR:始终编写 thenable 的 then 方法,就像编写 Promise 构造函数的 executor 参数一样。

关于javascript - 在 JavaScript ES6 中,thenable 的接受如何解决和拒绝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59492809/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com