新人入门,请多多指教。 生成一个随机数,如果大于0.9则返回成功,否则返回失败,并重新生成随机数,直到返回成功为止。 怎样用Promise 来写? (相当于请求一个网址,成功返回请求成功,失败则继续请求,直到成功为止)如果失败后等待一秒再请求呢,该咋样写?
我用的是bluebird
你的问题好像和Promise关系不大,简单的回调就搞定了。Promise是为异步编程提供一种同步抽象,就是可以有返回值和catch异常。一般在一个想对复杂的异步流程里面会非常有用,对于这种,我一般会用组合的方式,就是前一个promise的返回作为下一个的输入,然后在最后面catch异常。如果你能将promise和generator结和一下,那写出的代码想对就比较优雅了。
之前的代码delay有问题,特地重构了下。假设有一个HTTP请求
function fetchComList() { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open('GET', '/companies', true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { xhr.status === 200 ? resolve(xhr.responseText) : reject(xhr.responseText); } }; xhr.send(); }); }
function promiseRetry(opts) { var originalFn; //设置 opts = Object.assign({ times: 0, delay: 0 }, opts); return function exec(fn) { if (!originalFn) originalFn = fn; return fn().catch(function (error) { if (opts.times-- <= 0)return Promise.reject(error); return exec(delay); }); }; //延时处理 function delay() { return new Promise(function (resolve) { setTimeout(function () { resolve(originalFn()); }, opts.delay); }) } } var promiseRetryInstance = promiseRetry({times: 2, delay: 2000}); promiseRetryInstance(fetchComList).then(function (data) { console.log(data) }).catch(function (err) { console.log(err); });
@htoooth 提到的Rxjs版本
function rxRetry(fn, opts) { opts = Object.assign({ times: 0, delay: 0 }, opts); return Rx.Observable .defer(function () { return fn(); }) .retryWhen(function (errs) { return errs .zip(Rx.Observable.range(1, opts.times), function (x, y) { return y }) .flatMap(function () { return Rx.Observable.timer(opts.delay); }); }) } rxRetry(fetchComList, {times: 2, delay: 2000}).subscribe(function (data) { console.log(data); }, function (err) { console.log(err) });
楼上已经帮你回答了,不过同步的东西为什么要封装成promise
import Rx from "rx"; let count = 0; const random = (cb) => { console.log("one" + (count++)); let result = Math.random(); if (result > 0.9) { cb(null, result); } else { cb("error"); } }; const source = Rx.Observable.defer(() => Rx.Observable.fromNodeCallback(random)()) .retryWhen(err => err .zip(Rx.Observable.range(1, 3), (x, y) => y) .flatMap(x => Rx.Observable.timer(1000)) ); const subscription = source.subscribe( function(x) { console.log('Next: ' + x); }, function(err) { console.log('Error: ' + count); }, function() { console.log('Completed' + count); });
这种情况就很种使用,rxjs,而不是 promise。
var Promise = require('bluebird'); function request() { return new Promise(function (resovle, reject) { setTimeout(function() { var num = Math.random(); if(num > 0.8){ resovle(num); }else{ reject(num); } },1000); }) } function digui() { return request().then(function(res) { console.log('成功 ' + res); return; }).catch(function(err) { console.log('失败 ' + err); return digui(); }) } digui().done();
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
我用的是bluebird
你的问题好像和Promise关系不大,简单的回调就搞定了。Promise是为异步编程提供一种同步抽象,就是可以有返回值和catch异常。一般在一个想对复杂的异步流程里面会非常有用,对于这种,我一般会用组合的方式,就是前一个promise的返回作为下一个的输入,然后在最后面catch异常。如果你能将promise和generator结和一下,那写出的代码想对就比较优雅了。
之前的代码delay有问题,特地重构了下。假设有一个HTTP请求
Promise Retry
Rxjs Retry
@htoooth 提到的Rxjs版本
楼上已经帮你回答了,不过同步的东西为什么要封装成promise
这种情况就很种使用,rxjs,而不是 promise。