2016-01-27 213 views
0

我正在学习nodejs中的承诺,下面是我的示例代码。 的下面的代码的输出是 试验 - 1个 试验 - 2 试验 - 3 测试 - 4nodejs中的循环承诺

var Q = require('q'); 
var promise = Q.when('test'); 

promise.then(function(val) { 
console.log(val + '-' + '1'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '2'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '3'); 
}); 

promise.then(function(val) { 
console.log(val + '-' + '4'); 
}); 

我想知道如何可以使用用于循环写相同的代码。

+0

你在学习循环,承诺还是两者?你已经知道JS中的循环和回调了吗? – Bergi

+0

@Bergi,我尝试下面的代码 var Q = require('q'); var promise = Q.when('test'); (var idx = 1; idx <= 4; idx ++){ promise.then(function(val){ console.log(val +' - '+ idx); }); } 但是输出是测试-5测试-5测试-5测试-5 – refactor

+1

啊是的,这只是[臭名昭着的闭环在循环问题](http://stackoverflow.com/q/1451009/1048572) – Bergi

回答

1

最后,我可以做我想要,下面是代码

var Q = require('q'); 
var promise = Q.when('test'); 

for(var idx = 1 ; idx <= 4 ; idx++) 
{ 
    (function() 
    { 
     var temp = idx; 
     promise.then(function(val) { 
      console.log(val + '-' + temp); 
      }); 

    })(); 
} 

它的工作原理!我保证:)

0

qdocumentation

如果你想运行的功能,动态构建的序列, 你会想是这样的:

var funcs = [foo, bar, baz, qux]; 

var result = Q(initialVal); 
funcs.forEach(function (f) { 
    result = result.then(f); 
}); 
return result; 

哪里initialVal是你Q.when('test')

1

这实际上并非特定于承诺。如果你在回路中创建回调,you'll need an extra closure scope,除此之外它是相当标准的。

但是,对于您的特定情况,最简单的方法是仅使用单个回调,因为它们都附加到相同的承诺,并且会收到相同的值。所以你用

require('q').when('test').then(function(val) { 
    for (var i=1; i<=4; i++) { 
     console.log(val + '-' + i); 
    } 
}); 
-1

首先,因为有本土ES6承诺,我认为这是不,除非你有支持旧的浏览器或旧版本的NodeJS使用一个库是个好主意。

当您使用promise时,您正在使用异步代码,因此,您可以以不同的方式进行循环。

想象一下,你有这样的片段:

function step1 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 1 for item ' + item); 
    }, 1000); 
    }); 
} 

function step2 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 2 for item ' + item); 
    }, 1000); 
    }); 
} 

function step3 (item){ 
    return new Promise((resolve, reject) => { 
    setTimeout(()=>{ 
     resolve('step 3 for item ' + item); 
    }, 1000); 
    }); 
} 

function processItem (item) { 
    return step1(item).then(result =>{ 
    console.log(result); 
    return step2(item); 
    }).then(result =>{ 
    console.log(result); 
    return step3(item); 
    }).then(result =>{ 
    console.log(result); 
    return ('finished process of item ' + item); 
    }).catch(err =>{ 
    throw (err); 
    }); 
} 

其中processItem功能将被应用到项目阵列。

  • A.运行一个foor循环。

上面的代码是异步的,所以,当你运行它,然后inmediatly执行下一个,所以,如果processItem功能需要3秒完成,并且要将该功能应用于10个项目,这将需要3秒钟,因为Promise呼叫将被严格执行,但无需等待完成其中的任何一个。

示例代码:

function promiseFor(set, fn){ 
    return new Promise((resolve, reject) => { 
     return arr.map(item =>()=> fn(item)).forEach(proc => { 
     return proc().then(res => { 
      resolve(); 
     }).catch(err=>{ 
      console.log(err); 
     }); 
     }); 
    }); 
} 
  • B.运行序列中的承诺。 顺序没有开始,直到前一个已经执行到执行任何承诺,这就像一个非异步福尔循环: 例子:
function sequence (set, fn){ 
    return set.map(item =>()=> fn(item)).reduce((curr, next)=> { 
    return curr.then(()=>{ 
     return next(); 
    })},Promise.resolve()); 
}