2017-06-15 62 views
2

我有一些函数返回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 S的两个被调用,同时在一开始,一切是关闭的。我想输出是一样的东西:

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

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

回答

1

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

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>

+0

啊,我知道了,谢谢。像这样嵌套他们是唯一的方法来做到这一点?所以,如果我说,用for循环构建一个长链或者我需要编写一些辅助函数来顺序执行,或者将所有内容都嵌入到这个嵌套表单中? –

+1

一旦推迟解决,它将执行附加到它的所有then(),而不管其中是否包含另一个延迟与否。所以你必须牢记你的逻辑。 – Taplar

+0

顺便说一句,我做了一个实验,玩你的建议,它实际上*出现*正常工作,如果我*只是*使第二次调用测试是一个函数(返回延迟对象),即使没有嵌套,[像这个](https://pastebin.com/r5Eda5Zp)。也许如果'then'处理程序返回可靠的东西,它会改变链中其余部分的运行? –