ES6解构的承诺?

时间:2017-11-25 14:44:47

标签: javascript node.js ecmascript-6 promise

我尝试将Promises与ES6解构语法混合(仅用于实验目的),但以下代码会引发错误:

function delay(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(), ms)
  })
}

const { then } = delay(2000)

console.log(typeof then) // ==> 'function'

// throws TypeError:
then(() => {
  console.log(`done!`)
})

在Node.js v7.10.1上打印:

  

TypeError:无法读取未定义的属性'Symbol(promise_state_symbol)'

Chrome控制台还会抛出TypeError,但会显示不同的消息:

  

Uncaught TypeError:方法Promise.prototype.then调用不兼容的接收器undefined

这些错误对我说不多。对此有什么更好的解释?

2 个答案:

答案 0 :(得分:3)

这意味着then是一种方法而你没有在任何实例上调用它 - 你只是把它称为一个没有this context的函数(或者#34;接收器",as as第二条错误消息正确命名它)。你基本上做了

const then = Promise.prototype.then
console.log(typeof then) // ==> 'function'
then(() => {}) // throws TypeError

您可以使用call

const promise = delay(2000);
then.call(promise, console.log);

或只是正确调用promise.then(console.log)

答案 1 :(得分:1)

您正在为变量分配then方法,但then访问this。您可以使用bind来实现您想要的目标。

基本上,javascript中的方法只是使用this的函数。如果您“窃取”该功能并且没有提供此值,则您处于危险区域。

您提取的then最有可能来自Promise.prototype,而不是特定于延迟功能的功能。

你刚刚发现了一种从对象中获取方法的奇特方法。它完全没有与去除相关...

let p;
const {then} = p = delay(2000);
const then1 = p.then;

console.assert(then === Promise.prototype.then)
console.assert(then1 === then, 'thens aren\'t the same')

但你想要一个then,以某种方式确保你在正确的承诺上称之为。{/ p>

所以你可以选择

const p = delay(2000);
const then = p.then.bind(p);
…

或构建另一个匿名函数

const p = delay(2000);
const then = fn => p.then(fn)

请注意,这不是您想要的,因为它会在您拨打then时启动超时。

const then = fn => delay(2000).then(fn) // ⚠ setTimeout gets called when you are calling then.

我认为你不可能在一条线上实现你想要的东西,但也许其他人有一个想法。