繁体   English   中英

循环承诺,连锁承诺

[英]While loop promise, chain promise

我有一个脚本,如果此操作失败,应尝试将其连接到服务器3次,将用户导航到“ No Connection page

我不知道如何尝试尝试3次连接,然后在失败的情况下No Connection page用户导航到“ No Connection page

如何使用我的代码来解决此问题。

这是我到目前为止的代码:

const fetchModule = require('fetch');
const frameModule = require('ui/frame');

let timeTrig;
const waitPeriod = 7000;

function checkServerStatus() {
    if (timeTrig) {
        clearTimeout(timeTrig);
        timeTrig = null;
    }
    timeTrig = setTimeout(() => {
    frameModule.topmost().navigate('./views/no-connection');
    }, waitPeriod);
    return fetchModule.fetch(`${randomUrl}auth/ping`)
        .then((result) => {
            clearTimeout(timeTrig);
            if (result && result.ok) {
                return true;
            }
            frameModule.topmost().navigate({
                moduleName: views/no-connection,
                transition: {
                    name: 'slide',
                },
            });
        })
        .catch(() => {
            if (timeTrig) {
                clearTimeout(timeTrig);
                timeTrig = null;
            }
            frameModule.topmost().navigate({
                moduleName: 'views/no-connection',
                transition: {
                    name: 'slide',
                },
            });
        });
}

任何帮助表示赞赏。

也许您想要这样的东西-不完全确定应重试代码的哪一部分,但这可能会给您一些想法

const fetchModule = require('fetch');
const frameModule = require('ui/frame');

const waitPeriod = 7000;

// retry "cont" times or until the promise resolves
const retry = (cont, fn) => fn().catch(err => cont > 0 ? retry(cont - 1, fn) : Promise.reject(err));

// failure code - reason will be the last failure reason ('not ok' or 'timeout') - not that it is used in your code
const noConnection = reason => frameModule.topmost().navigate({
    moduleName: 'views/no-connection',
    transition: {
        name: 'slide',
    },
});

// lets race between (resolved or rejected) fetch and a rejected timeout
const doFetch = () => Promise.race([
    fetchModule.fetch(`${randomUrl}auth/ping`).then(result => {
        if (result && result.ok) {
            return true;
        }
        return Promise.reject('not ok');
    }),
    // above can be written as
    // fetchModule.fetch(`${randomUrl}auth/ping`).then(result => (result && result.ok) || Promise.reject('not ok')),
    new Promise((resolve, reject) => setTimeout(reject, waitPeriod, 'timeout'))
]);

const checkServerStatus = () => {
    retry(3, doFetch).catch(noConnection)
};

另外,这是相同的代码,只是组织方式不同。 我认为更好:p

const fetchModule = require('fetch');
const frameModule = require('ui/frame');

const waitPeriod = 7000;

// retry "cont" times or until the promise resolves
const retry = (cont, fn) => fn().catch(err => cont > 0 ? retry(cont - 1, fn) : Promise.reject(err));
// reject after a given timeout
const delayedReject = (delay, reason) => new Promise((_, reject) => setTimeout(reject, delay, reason));
//
const doFetch = () => fetchModule.fetch(`${randomUrl}auth/ping`)
.then(result => (result && result.ok) || Promise.reject('not ok'));

const checkServerStatus = () => retry(3, () => Promise.race([doFetch(), delayedReject(waitPeriod, 'timeout')]))
.catch(reason => frameModule.topmost().navigate({
    moduleName: 'views/no-connection',
    transition: {
        name: 'slide',
    },
}));

这种“尝试n次,然后失败”的类型的问题经常出现,以http提取或Web套接字的形式出现,而没有出现。 我之前实际上已经实现了诺言的TryNTimes功能。

这是一个更有趣的版本,我认为它非常优雅且可重复使用。

我们有几个实用程序功能,它们只是用来模仿获取请求和承诺排序。

下面的bring功能就像获取概率为50%的提取一样。

bring    = (url,i) => new Promise((v,x) => Math.random() > 0.50 ? v(`Data from ${url}`) : x(`Error @ promise # ${i}`))

接下来,我们设置大小为n的此类bring函数的数组。

promises = (f,n) => Array(n).fill(f),

接下来,我们对promise返回的bring函数进行递归排序。 如果被调用的bring函数返回的Promise解析,我们将返回该分辨率,但是如果拒绝,则继续处理数组中的下一个,直到不再剩余。 显然,数组的大小是尝试计数。

 var bring = (url,i) => new Promise((v,x) => Math.random() > 0.50 ? v(`Data from ${url}`) : x(`Error @ promise # ${i}`)), promises = (f,n) => Array(n).fill(f), tryProms = ([f,...fs], url, i = 1) => f(url,i).then(v => `${v} @ try # ${i}`, e => (console.log(`Failed @ try #${i}`), fs.length ? tryProms(fs,url,++i) : `All ${i} tries are failed`)); tryProms(promises(bring,3),"http://www.someAPI/data").then(console.log, console.log); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM