将属性附加到Promise

时间:2017-07-23 19:10:42

标签: javascript es6-promise

关于SO的另一个问题让我有兴趣创建一个返回Promise和timerId的setTimeout,但不会破坏向后兼容性。 This是我指的问题。

它只是询问_.delay underscore.js方法中的内部return语句是无关的还是有用的。这是代码块。

这是_.delay的代码:

// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
    var args = slice.call(arguments, 2);
    return setTimeout(function() { // this is to return the timerId
        return func.apply(null, args); // this guy right is in question
    }, wait);
};

考虑到setTimeout当前没有返回Promise,我提出了可能存在未来验证的想法,因为setTimeout有一天会返回一个promise。

为此,setTimeout需要返回一个timerId才能取消它。因此,要返回Promise,您需要将timerId附加到Promise,以便返回Promise并且可以访问timerId。

然后你可以修改clearTimeout以便在给定timerId时执行它现在的确切方式,但是对于Promise,它使用Promise.timerId来清除超时并取消Promise。 当然也需要实施承诺取消......

无论如何......我开始尝试一些有趣的事情,并且遇到了我无法解释的事情。如果您运行下面的代码段,您会在返回之前看到promise具有.timerId属性,但返回后该属性丢失。谁能解释一下呢?



function pseudoSetTimeout( func, wait ) {

    let timerId,
        promise = new Promise( ( resolve, reject ) => {
            timerId = setTimeout( () => {
                let returnVal = func();
                resolve( returnVal );
            }, wait );
        });

    promise.timerId = timerId;

    console.log( "promise before return: ", promise );

    return promise;
}

function callback() {
    return "Callback fired";
}

let timeout = pseudoSetTimeout( callback, 1000 )
    .then( ( val ) => {
      console.log( val );
    });

console.log( "returned promise: ", timeout );




3 个答案:

答案 0 :(得分:4)

then in:

pseudoSetTimeout( callback, 1000 )
    .then( ( val ) => {
      console.log( val );
    });

返回一个新的promise,它不是pseudoSetTimeout返回的那个。这是一个承诺,undefined作为承诺值,因为then回调不会返回任何内容。

您可以在分配期间不应用then来使其有效:



function pseudoSetTimeout( func, wait ) {

    let timerId,
        promise = new Promise( ( resolve, reject ) => {
            timerId = setTimeout( () => {
                let returnVal = func();
                resolve( returnVal );
            }, wait );
        });

    promise.timerId = timerId;

    console.log( "promise before return: ", promise );

    return promise;
}

function callback() {
    return "Callback fired";
}

let timeout = pseudoSetTimeout( callback, 1000 );
timeout.then( ( val ) => {
  console.log( val );
});

console.log( "returned promise: ", timeout );




因为then在使用promises时至关重要,并且通常用于链接它们,所以将自定义属性附加到promise的想法似乎会失去实用性。

答案 1 :(得分:0)

非常有趣的问题。

不知道它是如何在节点内部制作的,但如果查看蓝鸟的代码是任何迹象:https://github.com/petkaantonov/bluebird/blob/master/src/thenables.js

我的猜测是返回的Promise实际上是另一个对象。

答案 2 :(得分:0)

由于其他答案中提到的原因,我会返回一个'元组'而不是在承诺上使用属性:



r.text