Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.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 使用承诺的链接方法_Javascript_Promise - Fatal编程技术网

Javascript 使用承诺的链接方法

Javascript 使用承诺的链接方法,javascript,promise,Javascript,Promise,我正试着去理解承诺,我想我可以看到它们是如何运作的,比如说,你可以说做步骤1,步骤2,然后再做步骤3。 我使用节点获取(使用本机承诺)创建了这个下载函数 所以这一切都是按顺序执行的,我可以看到它是如何工作的 我有另一种方法,然后将CSV文件转换为JSON(同样使用promise) 当我一个接一个地调用这些函数时,第二个函数失败,因为第一个函数尚未完成 我是否需要将这两个函数调用封装在另一个承诺中,即使它们各自实现了承诺 如果我完全误解了这一点,请告知 当我一个接一个地调用这些函数时,第二个函数失

我正试着去理解承诺,我想我可以看到它们是如何运作的,比如说,你可以说做
步骤1
步骤2
,然后再做
步骤3

我使用
节点获取
(使用本机承诺)创建了这个下载函数

所以这一切都是按顺序执行的,我可以看到它是如何工作的

我有另一种方法,然后将CSV文件转换为JSON(同样使用promise)

当我一个接一个地调用这些函数时,第二个函数失败,因为第一个函数尚未完成

我是否需要将这两个函数调用封装在另一个承诺中,即使它们各自实现了承诺

如果我完全误解了这一点,请告知

当我一个接一个地调用这些函数时,第二个函数失败,因为第一个函数尚未完成

第一个有两个问题:

  • 它不会等待文件被写入;它所做的只是设置管道,而无需等待流程完成
  • 它不提供任何方式让调用方知道进程何时完成
  • 要处理第一个问题,您必须等待目标流上的
    finish
    事件(该
    pipe
    返回)。要处理第二个问题,你需要回报一个在实现之前不会兑现的承诺。大致如下(请参见
    **
    注释):

    然后,您可以对结果使用
    然后
    捕获
    ,以进入下一步:

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


    旁注:我还没有对其进行代码审查,但出现了
    csvToJson
    中的一个严重问题,也是一个小问题,@Bergi强调了第二个问题:

  • else
    逻辑周围缺少
    {
    }

  • 小问题是您有
    var data=data.toString()
    数据
    是该函数的一个参数,因此
    变量
    具有误导性(但无害)

  • 它无法正确处理
    readFile
    回调的
    else
    部分代码中的错误

  • 我们可以通过在
    else
    中执行
    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;
      });
    }
    

    您可以在第一个导出函数中
    返回
    。这样,它将返回承诺,以便您可以对其调用另一个
    then()
    。第一个函数错误地报告文件已写入,而实际上您所做的只是设置管道。设置管道并不意味着文件已写入;写入过程是异步的。您的
    csvToJson
    函数在
    else
    逻辑周围缺少关键的
    {
    }
    ,其中一些逻辑错误地缩进,但只有一部分(
    var data=data.toString();
    )实际上附加到
    的else
    。还建议您决定是否依赖自动分号插入,然后包括(或省略)
    一致。(请注意,ASI是一种纠错机制*,它可能会影响您的决定。或者不影响您的决定。:-)非常感谢您的评论和回答,如果我想进一步链接
    ,然后
    catch
    函数,我现在将介绍这些,我可以像您那样添加它们吗?或者它们会在第二个函数之后嵌套吗?希望这能让你sense@Richlewis:如果您想在当前完成的工作之后在
    csvToJson
    中执行其他操作,您当然可以使用
    then
    catch
    来实现我们在那里创建的承诺。@Richlewis:我应该注意,上面的一些代码看起来笨拙的部分原因是它混合了两个世界,旧的节点回调样式和承诺。如果您打算使用承诺(这是一个好主意),一般来说,通过将旧式函数(如
    fs.readFile
    )包装为启用承诺的版本,尽早进入承诺阶段可能会更好,这样在大多数代码中,您只需处理承诺链(甚至是
    async
    /
    wait
    )。有关此操作的详细信息,请参阅。比大括号更好的建议是:只将
    解析(数据)
    放在
    的else
    中,其余部分放在
    中,然后在
    回调中正确捕获异常
    
    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
    }
    
    theFunctionAbove("/some/url", "some-target")
        .then(() = {
            // It worked, do the next thing
        })
        .catch(err => {
            // It failed
        });
    
    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;
      });
    }