Node.js:Promise + 循环 + 延时

使用的promise库: https://www.npmjs.com/package/promise, 支持浏览器和node环境。node

npm install promise

示例1:延时

var Promise = require('promise');

var delay = function(millis) {
  var promise = new Promise(function (resolve, reject) {
    setTimeout(function() {  resolve(); }, millis);
  });
  return promise;
};

delay(10*1000).then(function() {
  console.log('hi');
}).then(function() {
  console.log('hi2');
  throw new Error('!~~~~');
}).catch(function(e){
  console.error('出现错误: ',e);
});

运行(10s后出结果):npm

hi
hi2
出现错误:  [Error: !~~~~]

示例2:串行+每次都延时

var Promise = require('promise');

var delay = function(millis) {
  var promise = new Promise(function (resolve, reject) {
    setTimeout(function() {  resolve(); }, millis);
  });
  return promise;
};
var p = delay(3*1000);
p.then(function() {
  console.log('hi');
  return delay(1*1000);
}).then(function() {
  console.log('hi2');
  return delay(1*1000);
}).then(function() {
  console.log('hi3');
  return delay(1*1000);
});

运行:promise

hi
hi2
hi3

示例3:串行+每次都延时 + 循环

var Promise = require('promise');

var delay = function(millis) {
  var promise = new Promise(function (resolve, reject) {
    setTimeout(function() {  resolve(); }, millis);
  });
  return promise;
};

var p = delay(3*1000);
for (var i=0; i<10; ++i) {
  p = p.then(function() {
    console.log('hi');
    return delay(1*10);
  });
}

运行结果是10行hi。浏览器

若是循环次数很大,例如100000000000次,会出现内存不足的错误:ui

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

这是为何呢?咱们在循环里加入console.log,看下运行结果:code

var Promise = require('promise');

var delay = function(millis) {
  var promise = new Promise(function (resolve, reject) {
    setTimeout(function() {  resolve(); }, millis);
  });
  return promise;
};

var p = delay(3*1000);
for (var i=0; i<10; ++i) {
 
  p = p.then(function() {
    console.log('hi');
    return delay(3*1000);
  });

  console.log(p);
}

运行结果:协程

Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
Promise { _45: 0, _81: 0, _65: null, _54: null }
hi
hi
hi
hi
hi
hi
hi
hi
hi
hi

能够看到,promise先所有生成后,才依次输出hi。也就是说 p.then(...)是当即返回的。递归

示例4:延时+基于递归实现的循环

var Promise = require('promise');

var delay = 1*1000;

var currentIter = 0;
var maxIter = 100000000;

var task = function() {
    return new Promise(function(resolve, reject) {
        setTimeout(function(){
            // do something
            console.log('task', currentIter );
            resolve();          
        }, 100);
    });
}

var run = function() {
    task().then(function(){
        setTimeout(function(){
            ++currentIter;
            console.log(currentIter);
            if (currentIter < maxIter)
                run();
        }, delay)
    });
}

run();

运行输出:内存

task 0
1
task 1
2
task 2
3
task 3
4
task 4
5
task 5
6
task 6
7
task 7
...
...

示例5:基于协程的循环+延时

例如使用co库:get

npm install co
var Promise = require('promise');
var co = require('co');

var delay = 1*1000;

var currentIter = 0;
var maxIter = 100000000;

var task = function() {
    return new Promise(function(resolve, reject) {
        setTimeout(function(){
            // do something
            console.log('task', currentIter);
            resolve();          
        }, 100);
    });
}

var sleep = function(ms) {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve()
        }, ms);
    });
}


co(function* () {
    for(; currentIter < maxIter; ++currentIter) {
        yield task();
        yield sleep(delay);
    }
    return 'hi';
}).then(function (value) {
    console.log('--', value);
}, function (err) {
    console.error('++', err.stack);
});

其余

http://stackoverflow.com/questions/22707475/how-to-make-a-promise-from-settimeout

相关文章
相关标签/搜索