2016-04-07 16 views
1

私はfs.readfileを使用して同期に問題があります。初めて要求をしないと、私は結果を返します。私は約束を使うことができ、Q from Kriskowalと便利なものを見つけました。 私はそれを試しましたが、成功しませんでした。私はそれをどのように実装するのか非常によく理解していませんでした。誰かがこれを手伝うことができれば、私は永遠に感謝します。このような状況での実装方法を約束しますか?

コード:あなたがしてループサイクル内のファイルを読み込もうとしますが、非同期な方法でされているようだ

"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; 

} 
+1

https://www.npmjs.com/package/promise-denodeify –

+1

さて、あなたはどのように約束を使用しようとしましたか?あなたの質問を編集してください。あなたはQ文書を読んだことがありますか? 'fs'メソッドを' Q'ヘルパー関数で呼び出して、それらから約束を得る例を見ましたか? – Bergi

答えて

2

オム。最初の質問は、なぜasyncがそれらのファイルを読んでいるのでしょうか?あなたは、常に同期方法でそれらを読むことができます:

var data=fs.readFileSync(fname, encoding); 

ところで、あなたがそれらを非同期読んでために...ループ保持したい場合は、約束のようなもの、あるいは、時限待ち以上の複合体を必要とします同期メカニズム。

あなたは、このように他のパッケージ/モジュールを使用せずに、それをシンプルに保つことができます。

/** 
     * 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 

をので、あなたは

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()); 
}); 

のようにそれを呼び出すことができ、これは非常に単純化していることに注意してくださいしかし、ほとんどの場合、配列を循環するときに機能します。ここで

は遊び場での簡単な実施例である:

最後に

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"/>

、完全な非同期たとえば、リストを巡回する際、XMLHttpRequestのの実行を延期する方法を示します。 ExecutionBlockは、SimpleRequestが応答した後にrejectresolveを呼び出すため、thenを呼び出す前にPromise the waitの実行を引き起こします。

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 \t 
 
      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" />

+1

例のおかげで@loretoparisi私はたくさんのことを学んだ – michelpm1

+0

@ michelpm1あなたは歓迎です、多分ループのためのすべての約束のようなより象徴的なタイトルを編集することができます。最後の例は、 XMLHttpRequest'をWebサイトのURLに... – loretoparisi

関連する問題