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

相關文章
相關標籤/搜索