varresult;// A function to simulate async request delayvarrequest=function(msec,mockedData,callback){setTimeout(function(){callback(mockedData);},msec);};varsample=[{msec:200,data:'stale'},{msec:100,data:'fresh'}];// 模拟`先发起请求后响应`的情景sample.forEach(function(item){request(item.msec,item.data,function(resp){result=resp;});});// wait 1s, we inspect the `result`setTimeout(function(){// we expect `result` to be `fresh`, but it is `stale`console.log(result);// => `stale`},1000);
varresult;varglobalMark=0;// A function to simulate async request delayvarrequest=function(msec,mockedData,callback){setTimeout(function(){callback(mockedData);},msec);};varsample=[{msec:200,data:'stale'},{msec:100,data:'fresh'}];// 模拟`先发起请求后响应`的情景sample.forEach(function(item){varlocalMark=++globalMark;request(item.msec,item.data,function(resp){if(localMark!==globalMark){return;}result=resp;});});// wait 1s, we inspect `result`setTimeout(function(){// now our `result` is `fresh`, just as expectedconsole.log(result);// => `fresh`},1000);
Promise正在已经成为解决异步问题的一大解决工具了,经过多年的实际考验,它甚至已纳入W3C规范,制定标准API了。所以回到这个问题,we should think in promise at the first place。
例如,上面的request方法我们实际可以写成Promise的形式:
123456789101112
// A function to simulate async request delayvarrequest=function(msec,mockedData){return$.Deferred(function(dfd){setTimeout(function(){dfd.resolve(mockedData);},msec);}).promise();};request(200,'some data').then(function(resp){console.log(resp);// => 'some data'});
varpromisify=function(fn){// Is `fn` thenable?returnfn.then?fn:function(){varargs=[].slice.call(arguments);return$.Deferred(function(){fn.apply(null,args.concat(this.resolve));}).promise();};};
promisify [ES6版本]
1234567
varpromisify=function(fn){// Is `fn` thenable?returnfn.then?fn:function(){varargs=Array.from(arguments);returnnewPromise(resolve=>voidfn(...args.concat(resolve)));};};
以下是将request方法promise化的例子:
12345678910111213
// A function to simulate async request delayvarrequest=function(msec,mockedData,callback){setTimeout(function(){callback(mockedData);},msec);};// decorate `request` with `promisify`request=promisify(request);request(200,'some data').then(function(resp){console.log(resp);// => 'some data'});
varresult;// A function to simulate async request delayvarrequest=function(msec,mockedData,callback){setTimeout(function(){callback(mockedData);},msec);};// decorate `request` with both `promisify` and `mutePrior`request=mutePrior(promisify(request));varsample=[{msec:200,data:'stale'},{msec:100,data:'fresh'}];// 模拟`先发起请求后响应`的情景sample.forEach(function(item){request(item.msec,item.data).then(function(resp){result=resp;});});// wait 1s, we inspect `result`setTimeout(function(){// now our `result` is `fresh`, just as expectedconsole.log(result);// => `fresh`},1000);