簡體   English   中英

使用promise的鏈接方法

[英]Chaining methods using promises

我正在努力兌現承諾,我想我可以看到它們的工作方式,例如您可以說先執行Step 1Step 2然后再執行Step 3
我已經使用node-fetch (使用本機Promises)創建了此下載功能

## FileDownload.js

const fetch = require('node-fetch');
const fs = require('fs');

module.exports = function(url, target) {
  fetch(url)
    .then(function(res) {
      var dest = fs.createWriteStream(target);
      res.body.pipe(dest);
    }).then(function(){
      console.log(`File saved at ${target}`)
    }).catch(function(err){
      console.log(err)
  });
}

所以這一切按順序執行,我可以看到它是如何工作的。

我有另一種方法,然后將CSV文件轉換為JSON(再次使用Promise)

## CSVToJson.js

const csvjson = require('csvjson');
const fs = require('fs');
const write_file = require('../helpers/WriteToFile');

function csvToJson(csv_file, json_path) {
  return new Promise(function(resolve, reject) {
    fs.readFile(csv_file, function(err, data){
      if (err)
        reject(err);
      else
        var data = data.toString();
        var options = {
          delimiter : ',',
          quote     : '"'
        };
      const json_data = csvjson.toObject(data, options);
      write_file(json_path, json_data)
      resolve(data);
    });
  });
}

module.exports = {
  csvToJson: csvToJson
}

當我一個接一個地調用這些功能時,第二個功能失敗,因為第一個功能尚未完成。

我是否需要將這兩個函數調用包裝在另一個promise中,即使它們各自實現了promise?

請告知我是否完全誤解了

當我一個接一個地調用這些功能時,第二個功能失敗,因為第一個功能尚未完成。

第一個有兩個問題:

  1. 它不等待文件被寫入;而是等待文件寫入。 它要做的就是設置管道,而無需等待過程完成
  2. 它沒有提供任何方式讓調用者知道過程何時完成

要處理第一個問題,您必須等待目標流( pipe返回)上的finish事件。 要處理第二個問題,您需要返回一個承諾,直到這種情況發生,該承諾才能兌現。 遵循以下原則(請參見**評論):

module.exports = function(url, target) {
  // ** Return the end of the chain
  return fetch(url)
    .then(function(res) {
      // ** Unfortunately, `pipe` is not Promise-enabled, so we have to resort
      // to creating a promise here
      return new Promise((resolve, reject) => {
        var dest = fs.createWriteStream(target);
        res.body.pipe(dest)
          .on('finish', () => resolve()) // ** Resolve on success
          .on('error', reject);          // ** Reject on error
      });
    }).then(result => {
      console.log(`File saved at ${target}`);
      return result;
    });
    // ** Don't `catch` here, let the caller handle it
}

然后,您可以使用thencatch結果以繼續進行下一步:

theFunctionAbove("/some/url", "some-target")
    .then(() = {
        // It worked, do the next thing
    })
    .catch(err => {
        // It failed
    });

(或async / await 。)


旁注:我尚未對其進行代碼審查,但csvToJson一個嚴重問題跳了出來,也是一個小問題,@ Bergi突出了第二個問題:

  1. else邏輯中缺少{}

  2. 小問題是您有var data = data.toString(); 但是data是該函數的參數,因此var具有誤導性(但無害)

  3. 它無法正確處理readFile回調的else部分中的部分代碼錯誤

我們可以通過在else進行resolve並在then處理程序中執行其余邏輯來解決這兩個resolve

function csvToJson(csv_file, json_path) {
  return new Promise(function(resolve, reject) {
    fs.readFile(csv_file, function(err, data){
      if (err)
        reject(err);
      else
        resolve(data);
    });
  })
  .then(data => {
    data = data.toString();
    var options = {
      delimiter : ',',
      quote     : '"'
    };
    const json_data = csvjson.toObject(data, options);
    write_file(json_path, json_data);
    return data;
  });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM