Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Async.js-已调用ETIMEDOUT和回调_Javascript_Node.js_Callback_Promise_Async.js - Fatal编程技术网

Javascript Async.js-已调用ETIMEDOUT和回调

Javascript Async.js-已调用ETIMEDOUT和回调,javascript,node.js,callback,promise,async.js,Javascript,Node.js,Callback,Promise,Async.js,当我运行index.js时,我一直收到一个ETIMEDOUT或ECONNRESET错误,后面是一个回调已被调用错误 起初我认为这是因为在调用onEachLimitItem回调之前没有包含return。所以我把它包括在每一页中。还是没有解决。我也尝试过删除错误事件和在错误事件中删除对onEachLimit的回调,但两者都不起作用。我已经研究了关于回调问题的其他SO问题,这些问题已经被调用了,但是因为它们与流无关,所以我没有找到解决方案 我的理解是,如果流遇到类似于ECONNRESET的错误,它将在

当我运行
index.js
时,我一直收到一个
ETIMEDOUT
ECONNRESET
错误,后面是一个
回调已被调用
错误

起初我认为这是因为在调用
onEachLimitItem
回调之前没有包含
return
。所以我把它包括在每一页中。还是没有解决。我也尝试过删除错误事件和在错误事件中删除对onEachLimit的回调,但两者都不起作用。我已经研究了关于
回调问题的其他SO问题,这些问题已经被调用了
,但是因为它们与流无关,所以我没有找到解决方案

我的理解是,如果流遇到类似于
ECONNRESET
的错误,它将在错误事件中返回回调,并转到下一个流,但情况似乎并非如此。如果错误自行解决,即重新连接并尝试将出错的蒸汽再次发送到Azure,那么它几乎可以正常工作,然后触发“完成”事件,并且我们得到了已调用的
回调

我是否正确处理流事件中的回调

var Q = require('q');
var async = require('async');
var webshot = require('webshot');
var Readable = require('stream').Readable;
var azure = require('azure-storage');

var blob = azure.createBlobService('123', '112244');
var container = 'awesome';

var countries = [
    'en-us', 'es-us', 'en-au', 'de-at', 'pt-br', 'en-ca', 'fr-ca', 'cs-cz', 'ar-ly', 'es-ve',
    'da-dk', 'fi-fi', 'de-de', 'hu-hu', 'ko-kr', 'es-xl', 'en-my', 'nl-nl', 'en-nz', 'nb-no',
    'nn-no', 'pl-pl', 'ro-ro', 'ru-ru', 'ca-es', 'es-es', 'eu-es', 'gl-es', 'en-gb', 'es-ar',
    'nl-be', 'bg-bg', 'es-cl', 'zh-cn', 'es-co', 'es-cr', 'es-ec', 'et-ee', 'fr-fr', 'el-gr',
    'zh-hk', 'en-in', 'id-id', 'en-ie', 'he-il', 'it-it', 'ja-jp', 'es-mx', 'es-pe', 'en-ph'
];

var uploadStreamToStorage = function (fileName, stream, onEachLimitItem) {
    var readable = new Readable().wrap(stream);
    var writeable = blob.createWriteStreamToBlockBlob(container, fileName);

    readable.pipe(writeable);

    writeable.on('error', function (error) {
        return onEachLimitItem.call(error);
    });

    writeable.on('finish', function () {
        onEachLimitItem.call(null);
    });
};

var takeIndividualScreenshot = function (ID, country, onEachLimitItem) {
    var fileName = ID + '-' + country + '.jpg';
    var url = 'https://example.com/' + country + '/' + ID;

    webshot(url, function (error, stream) {
        if (error) { throw 'Screenshot not taken'; }

        uploadStreamToStorage(fileName, stream, onEachLimitItem);

    });
};

var getAllCountriesOfId = function (ID) {
    var deferred = Q.defer();
    var limit = 5;

    function onEachCountry(country, onEachLimitItem) {
        takeIndividualScreenshot(ID, country, onEachLimitItem);
    }

    async.eachLimit(countries, limit, onEachCountry, function (error) {
        if (error) { deferred.reject(error); }
        deferred.resolve();
    });

    return deferred.promise;
};

var createContainer = function () {
    var df = Q.defer();
    var self = this;

    blob.createContainerIfNotExists(this.container, this.containerOptions, function (error) {

        if (error) { df.reject(error); }

        df.resolve(self.container);
    });

    return df.promise;
};

createContainer()
    .then(function () {
        return getAllCountriesOfId('211007');
    })
    .then(function () {
        return getAllCountriesOfId('123456');
    })
    .fail(function (error) {
        log.info(error);
    });

您已经知道,您的回拨电话会被呼叫两次。问题是,;您是要在迭代流时停止所有错误,还是要累积流中的所有错误

有多种方法可以捕获和处理您已经在执行的错误,但这是因为您没有抛出错误对象,从而导致数据流中的其他调用导致致命错误

代码中的实际问题是由于返回的范围造成的。处理错误并尝试返回回调并停止脚本执行时,小时返回的范围是streams错误处理程序的本地范围,而不是全局脚本,因此脚本将继续并捕获下一个有效流

writeable.on('error', function (error) {
   // This 'return' is in the local scope of 'writable.on('error')'
  return onEachLimitItem.call(error);
});
它可能会设置一个数组,然后在该函数本地范围之外处理错误。i、 e

// Set the array's scope as global to the writable.on() error 
var errResults = [];
writeable.on('error', function (error) {
  // Push the local scoped 'error' into the global scoped 'errResults' array
  errResults.push(error);
});

writeable.on('finish', function () {
  // Are there any errors?
  return (errResults.length > 0) ?
    onEachLimitItem.call(errors) : onEachLimitItem.call(null);
});
以上只是解决问题的一种方法

我不确定您是否阅读过Joyent(原始node.js语言支持者)提供的错误处理帮助,但它应该能让您很好地了解处理错误时的选项


Hi@jas-,我正在使用
Q
的失败错误侦听器,但只是将错误发送到我正在使用的记录器(我已将其添加到上述脚本中)。我希望从流中积累所有错误,而不是让脚本崩溃——我只是不知道如何做到这一点。现在阅读Joyent链接。我不熟悉Q,但正如我提到的,你的脚本不会因为错误而停顿,也不会被调用两次。这可能会发生(在您的情况下也是如此),因为您返回回调错误处理程序的作用域是“writeable.on()”错误处理函数的本地作用域。您能否提供一个如何处理错误的示例?谢谢,这对我来说是全新的。文档应该为您提供可用的选项。你必须决定哪种方法最适合你想要实现的目标。我注意到的一件事是,当我在我的虚拟机(3gb的RAM)上运行这个方法而不是在本地(8gb的RAM)上运行这个方法时,当我在我的虚拟机上运行它时,脚本会继续抛出
ECONNRESET
错误。