使用的promise库: https://www.npmjs.com/package/promise, 支持浏览器和node环境。node
npm install promise
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: !~~~~]
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
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(...)
是当即返回的。递归
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 ... ...
例如使用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