为node.js回调定义超时

时间:2014-12-30 14:10:32

标签: javascript node.js amazon-s3 callback

我在node.js中使用S3进行回调。

以下是代码:

FS.prototype.myfunc = function (base, url, size, callBackArg) {
    var s3ForHead = new AWS.S3({httpOptions:{timeout: 5000}});

    console.log("Define s3Forhead Object");

    s3ForHead.listObjects({
        "Prefix" : url,
        "Bucket" : S3_BUCKET
    }, function (err, data) {

        console.log("Callback is done");

        if (err != null) {
            console.log(err);
            callBackArg("404");
        } else {
            if (data.Contents.length > 0) {
                callBackArg("200");
            } else {
                callBackArg("404");
            }
        });
    }
}

由于某种原因,listObjects有时会在listObjects阶段冻结。

意思是,Callback is done没有打印到屏幕上。

我想在5000ms之后,如果回调没有返回,我将返回" 404"用我的callBackArg参数。

有什么方法可以使用node.js吗?

2 个答案:

答案 0 :(得分:0)

你需要这样的东西:

FS.prototype.myfunc = function (base, url, size, callBackArg) {
    var s3ForHead = new AWS.S3({httpOptions:{timeout: 5000}});

    var failed = false; // failed flag
    var timeout = setTimeout(function () {
        failed = true;   // set failed flag
        callback("404"); // callback with "404"
    }, 5000);

    console.log("Define s3Forhead Object");

    s3ForHead.listObjects({
        "Prefix" : url,
        "Bucket" : S3_BUCKET
    }, function (err, data) {

        console.log("Callback is done");

        if (err != null) {
            console.log(err);
            callBackArg("404");
        } else if (!failed) { // Check if not failed

            clearTimeout(timeout); // remove the timeout if the data is ready

            if (data.Contents.length > 0) {
                callBackArg("200");
            } else {
                callBackArg("404");
            }
        });
    }
}

答案 1 :(得分:0)

我不认为setTimeout会阻塞事件循环,它只是在x秒后将函数排队等待执行。所以你可以使用变量来检查回调是否被触发。你也可以在里面调用setTimeout FS.prototype func但在listobjects之后。

FS.prototype.myfunc = function(base, url, size, callBackArg) {
    var timeout = true;//will be true before the callback is fired
    var s3ForHead = new AWS.S3({
        httpOptions: {
            timeout: 5000
        }
    });
    console.log("Define s3Forhead Object");
    s3ForHead.listObjects({
        "Prefix": url,
        "Bucket": S3_BUCKET
    }, function(err, data) {
        timeout = 'false';//set to false here since callback is fired
        console.log("Callback is done");
        if (err != null) {
            console.log(err);
            callBackArg("404");
        } else {
            if (data.Contents.length > 0)
                callBackArg("200");
            else
                callBackArg("404");
        }
    });
    setTimeout(function() {
        if (timeout) return callback("404");//Only call 404 if callback is not fired
    }, 5000);
    console.log('see settimeout does not block');//settimeout does not block,it executes callback after x secs.
};