使用的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