return 延迟对象的链接函数

Chaining functions that return deferred objects

我有一些 return jQuery 延迟对象的函数,但我无法理解如何链接它们并处理结果。

考虑以下示例:

const start = Date.now();

// Print a message with a timestamp.
function log (v) {
    console.log(`${Date.now() - start} ${v}`);
}

// Return a deferred function that resolves 1 second later with 'value'.
function test (value) {
    log(`test(${value})`);
    return $.Deferred(function (def) {
        window.setTimeout(function () {
            log(`resolve(${value})`);
            def.resolve(value);
        }, 1000);
    });
}

// Example:
test(42)
    .then(function (v) { log(v); })
    .then(test(99))
    .then(function (v) { log(v); })
    .then(function () { log('done'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

这是假设到运行test(42),然后用它的结果做一些事情,然后运行test(99)然后做有这些结果的东西,一切都井井有条。然而,它实际上输出(第一个数字是自程序启动以来的毫秒数):

0 test(42)
0 test(99)
1003 resolve(42)
1003 42
1003 undefined    <-- supposed to be 99
1005 done
1005 resolve(99)

所以两个 test 在一开始就同时被调用,其他一切都关闭了。我想要它输出的是这样的:

0 test(42)
1000 resolve(42)
1000 42
1000 test(99)
2000 resolve(99)
2000 99
2000 done

我怎样才能完成这项工作?我尝试 returning $.Deferred(...).promise(),但行为没有任何变化,我也尝试使用 done 而不是 then,但唯一的变化是它打印了 42 a第二次而不是 undefined.

每个延迟只解析一次。对于每个延迟链,您必须正确附加它们。另外,第二次调用 test 需要在一个函数中,这样它就不会立即执行。

const start = Date.now();

// Print a message with a timestamp.
function log (v) {
    console.log(`${Date.now() - start} ${v}`);
}

// Return a deferred function that resolves 1 second later with 'value'.
function test (value) {
    log(`test(${value})`);
    return $.Deferred(function (def) {
        window.setTimeout(function () {
            log(`resolve(${value})`);
            def.resolve(value);
        }, 1000);
    });
}

// Example:
test(42)
    .then(function (v) { log(v); })
    .then(function () {
        test(99)
           .then(function (v) { log(v); })
           .then(function () { log('done'); });
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>