Promise.all([3,1,5].map(function (row,i) {
--return new Promise(function (resolve, reject) {
----setTimeout(function(){resolve(row)},i*100);
--}).then(function(row){
----return new Promise(function (resolve, reject) {
------ //resolve(row+1);
------reject(new Error(‘http 返回状态’))
----}).then((row)=>{return row+2},(err)=>{err=err||new Error();console.log(http err ${err.message||err}
);throw new Error(http err: ${err.message||err}...
)})
--}).then((row)=>{return row},(err)=>{console.log(wait err ${err.message||err}
);throw new Error(wait err: ${err.message||err}
)});
})).then(function(args){console.log(args,ok
)})
.catch((err)=>{console.log(Promise.all触发 reject: ${err.message}
)});
//实为URL列表+HTTP.get请求 每隔1秒请求1个; //写的很丑,3层Promise 3层then //http可以触发Promise.all的reject,然而剩下的timer怎么clear 修改后可以cleartimer了,小伙伴们有没有then递归式的
排版惨不忍睹
来自酷炫的 CNodeMD
没法呀 这里支持ACE 还是CodeMirror
用markdown重排一下啊,好难看。。。。
- setTimeout和发送请求本身是耦合的,没有必要为了拆开来强行加一层Promise
- function() 和 => 混用不好,你完全可以花点时间至少解决这个问题,代码会好读不少,但你太懒,pia!扔给我们
- 如果只是为了用row来计数,并且出错的时候取消所有timer,也不需要这么麻烦,我不知道我理解得对不对
- HTTP error也不需要重新封装,一般AJAX库的的error object已经包含了所需要的信息
Promise.all(
[3, 1, 5].map((row, i) => {
return new Promise((resolve, reject) => {
let timer = setTimeout(() => {
sendHTTPRequest()
.success((res) => {
!!window.rows__ ? window.rows__++ : window.rows__ = 0;
resolve(res);
}
.fail((err) => {
// 此时window.timers__已经建好了,可以立即清除
window.timers__.forEach((timer) => clearTimeout(timer));
delete window.timers__;
reject(err));
}
}, i * 100);
(windows.timers__ = window.timers__ || []).push(timer);
});
});
)
.then(
(responses) => { ... }
(err) => {
// window.rows__
// window.timers__.forEach() 也可以放在这里做
}
)
总的来说,碰到这种奇怪的代码,应该先想想有没有必要,而不是假设它有必要了,再试图去用“聪明”的代码方法去解决带啦的问题,能简单为什么不简单呢。
var timers=[],urls=['http://sina.com/list=00001','http://sina.com/list=00002','http://sina.com/list=00003'];
Promise.all(urls.map((url,i)=>{
return new Promise(function (resolve, reject) {
let timer=setTimeout(()=>{
http.get(url,(res)=>{
var chunks = [],size=0;
res.on('data',chunk=>{chunks.push(chunk),size += chunk.length});
res.on('end' ,()=> res.statusCode==200
?resolve(Buffer.concat(chunks,size).toString())
:reject("get error statusCode: " + res.statusCode)
);
}).on('error',(err)=>{
reject (`http 第${i}次出错`)
});
},i*100);
timers.push(timer)
})
})).then(datas=>{
console.log(`全部返回`,datas)
})
.catch(err=>{
console.log(`Promise.all err ${err}`);
timers.forEach(timer=>clearTimeout(timer))
});
setTimeout跟请求放一起确实好看多了
@neechange 这类问题(多个promise)的最优解我个人认为是RxJS (Observable) https://www.delivoper.com/t/rxjs-observable/38 用类似 https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/concat.md 然后.subscribe(fn),和Promise不同的是,subscribe中的fn会被执行n此,这样就不要Promise.all()这样的步骤了,代码会更好理解。
就不展开了,有兴趣去看吧。
一些方法可以抽出来,可以有效的减少几层^_^
来自酷炫的 CNodeMD
三层就不行了?我觉得到七八层的时候,你才不能容忍。 Promise 也没有很好的办法进行控制,一但使用 Promise,then 传染到四处。如果你要递归可以使用,直接在 then 中调用你的函数就何以了。现阶段,如果 async/await 不能使用的话,yield 是非常好的选择。你一但学会使用,就觉得世界清静了,回到了没有回调的世界。
@flamingtop 又来一个rxjs,rxjs概念太多,错误处理的方法跟一般的还不一样。学起来很陡峭,不会一但学会,那个爽。话说,你们有在生产环境中使用这个东西吗?对团队要求太高了。
@htoooth 刚开始理解概念需要点耐心,但一旦理解了也还好。做Angular 2开发,RxJS很重要。
@flamingtop 好新潮啊,Angular2 都在使用,团队强大hold得住。