[英]Promise how to implement in this situation?
i have a problem with sync using fs.readfile, they are not inicializing at the first time, if i try request again, then i have results. 我在使用fs.readfile进行同步时遇到问题,它们在第一次没有初始化,如果我再次尝试请求,那么我会得到结果。 I know i can use promise and i find something useful with Q from Kriskowal .
我知道我可以使用promise,并且在Kriskowal的Q中找到有用的东西。 I tried it but without success.
我尝试过但没有成功。 I didn´t understand very well how to implement it.
我不太了解如何实施。 If someone can help with this, i will be eternally grateful.
如果有人可以提供帮助,我将永远感激不已。
code: 码:
"use strict"
var Q = require('q');
var fs = require('fs');
var arrayZipBand = [];
var jsonZipCode = [];
var arrayParsedZipcodeBr = [];
exports.parse = function(opts) {
if (opts.zipBand.constructor != Array) {
opts.zipBand = [opts.zipBand];
}
if (opts.location.constructor != Array) {
opts.location = [opts.location];
}
if (opts.config === 0) {
opts.zipBand.forEach(function(file) {
fs.readFile(file, 'utf8', function(err, logData) {
if (err) throw err;
let text = logData.toString();
decodeURIComponent(text);
let lines = text.split('\n');
lines.forEach(function(line) {
let parts = line.split('@');
if (parts[1] != undefined) {
let obJson = {
LOC_NU: parts[0],
LOC_CEP_INI: parts[1],
LOC_CEP_FIM: parts[2]
}
arrayZipBand.push(obJson);
}
});
});
});
opts.location.forEach(function(file) {
fs.readFile(file, 'utf8', function(err, logData) {
if (err) throw err;
let text = logData.toString();
decodeURIComponent(text);
let lines = text.split('\n');
lines.forEach(function(line) {
let parts = line.split('@');
if (parts[1] != undefined) {
for (let i = 0; i < arrayZipBand.length; i++) {
if (parts[0] == arrayZipBand[i].LOC_NU) {
jsonZipCode.push(arrayZipBand[i]);
}
}
if (jsonZipCode === undefined) {
throw "Was not possible to find Zipcode for the id " + parts[0];
}
for (let i = 0; i < jsonZipCode.length; i++) {
let obJson = {
LOC_NU: parts[0],
UFE_SG: parts[1],
LOC_NO: parts[2],
MUN_NU: parts[8],
LOC_CEP_INI: jsonZipCode[i].LOC_CEP_INI,
LOC_CEP_FIM: jsonZipCode[i].LOC_CEP_FIM
}
arrayParsedZipcodeBr.push(obJson);
}
jsonZipCode = [];
}
});
});
});
};
return arrayParsedZipcodeBr;
}
uhm it seems you are trying to read files in the loop cycle then, but in a async way. 嗯,看来您正在尝试在循环周期中读取文件,但采用异步方式。 First question, is why async reading those files?
第一个问题,为什么要异步读取这些文件? You can always read them in sync way:
您始终可以以同步方式阅读它们:
var data=fs.readFileSync(fname, encoding);
By the way, if you wish to read them async and keep the for...loop you need something like a Promise, or a timed wait or a more complex synchronization mechanism. 顺便说一句,如果您希望异步读取它们并保持for ...循环,则需要诸如Promise,定时等待或更复杂的同步机制之类的东西。
You can keep it simple, without using any other packages/modules in this way: 您可以保持简单,而无需通过这种方式使用任何其他包/模块:
/**
* Promise.All
* @param items Array of objects
* @param block Function block(item,index,resolve,reject)
* @param done Function Success block
* @param fail Function Failure block
* @example
promiseAll(["a","b","c"],
function(item,index,resolve,reject) {
MyApp.call(item,function(result) {
resolve(result);
},
function( error ) { reject(error); }):
},
function(result) { // aggregated results
},function(error) { // error
})
* @author Loreto Parisi (loretoparisi at gmail dot com)
*/
promiseAll: function(items, block, done, fail) {
var self = this;
var promises = [],
index = 0;
items.forEach(function(item) {
promises.push(function(item, i) {
return new Promise(function(resolve, reject) {
if (block) {
block.apply(this, [item, index, resolve, reject]);
}
});
}(item, ++index))
});
Promise.all(promises).then(function AcceptHandler(results) {
if (done) done(results);
}, function ErrorHandler(error) {
if (fail) fail(error);
});
}, //promiseAll
so you can call it like 所以你可以这样称呼它
promiseAll(arrayOfItems, function(item, index, resolve, reject) {
// do something on item
if (someSuccessCondOnThisItem) {
resolve(item)
} else {
reject(new Error("operation failed"))
}
}, function(results) { // aggregated results
console.log("All done %d", results.length);
}, function(error) { // error
console.log(error.toString());
});
Keep in mind that this is a very simplified approach, but in most of cases it works when cycling through arrays. 请记住,这是一种非常简化的方法,但是在大多数情况下,当遍历数组时它可以工作。
Here is a simple working example in the playground: 这是操场上的一个简单的工作示例:
var console = { log : function(s) { document.getElementById("console").innerHTML+=s+"<br/>"} } var promiseAll= function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll arr=[1,2,3] promiseAll(arr ,function(item,index,resolve,reject) { console.log("Resolving item[" + index+"]") var okCond=true if(okCond) {resolve(item)} else { reject(new Error("item[" + index+"]")) } } ,function(results) { // aggregated results console.log("All done of "+results.length); } ,function(error) { // error console.log(error); });
<div id="console"/>
Finally, a complete asynchronous example, showing how to defer execution of a XMLHttpRequest, when cycling through a list. 最后,一个完整的异步示例,显示了在循环浏览列表时如何推迟执行XMLHttpRequest。 The
ExecutionBlock
is calling reject
and resolve
after the SimpleRequest responds, causing the Promise the wait its execution before calling the then
. ExecutionBlock
在SimpleRequest响应后正在调用reject
并resolve
,从而导致Promise在调用then
之前等待其执行。
var console = { log: function(s) { document.getElementById("console").innerHTML += s + "<br/>" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // state changes request.onreadystatechange = function() { if (request.readyState === 4) { // done if (request.status === 200) { // complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { SimpleRequest.call('https://icanhazip.com/', function(result) { if (result) { console.log("Response[" + index + "] " + result); resolve(result); } else { reject(new Error("call error")); } }) } arr = [1, 2, 3] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results)); }, function(error) { // error console.log(error); });
<div id="console" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.