为什么这些.then()发生故障?

时间:2017-11-17 00:55:32

标签: javascript node.js es6-promise

我有一个<mat-toolbar style="background:purple"> <mat-button-toggle (click)="sidenav.toggle()"><i class="material-icons" style="color:white">menu</i></mat-button-toggle> </mat-toolbar> <mat-sidenav-container> <mat-sidenav #sidenav style="width: 20%;"> <mat-selection-list> <mat-list-item>Item one</mat-list-item> <mat-list-item>Item two</mat-list-item> <mat-list-item>Item one</mat-list-item> <mat-list-item>Item one</mat-list-item> <mat-list-item>Item one</mat-list-item> </mat-selection-list> </mat-sidenav> <router-outlet></router-outlet> </mat-sidenav-container> <!DOCTYPE html> <html style="height:100%;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - RemoteTrainer</title> <base href="~/" /> <link href="~/dist/deeppurple-amber.css" rel="stylesheet" /> <link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" /> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" type="text/javascript"></script> </head> <body> @RenderBody() @RenderSection("scripts", required: false) </body> </html> <h1>Hello, world!</h1> <p>Welcome to your new single-page application, built with:</p> <ul> <li><a href='https://get.asp.net/'>ASP.NET Core</a> and <a href='https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx'>C#</a> for cross-platform server-side code</li> <li><a href='https://angular.io/'>Angular</a> and <a href='http://www.typescriptlang.org/'>TypeScript</a> for client-side code</li> <li><a href='https://webpack.github.io/'>Webpack</a> for building and bundling client-side resources</li> <li><a href='http://getbootstrap.com/'>Bootstrap</a> for layout and styling</li> </ul> <p>To help you get started, we've also set up:</p> <ul> <li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li> <li><strong>Server-side prerendering</strong>. For faster initial loading and improved SEO, your Angular app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over.</li> <li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li> <li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular app will be rebuilt and a new instance injected is into the page.</li> <li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li> </ul> <button mat-fab>Click Me</button> <mat-slider min="1" max="5" step="0.5" value="1.5"></mat-slider> spawn的节点应用程序。当child_process完成运行时,我想解决一个承诺。以下代码有效,但child_process语句不按顺序发生:

.then()

我得到的输出是:

const storage = require('./storage');
const logging = require('./logging');
const process = require('child_process').spawn;


function convertIncomingFile(pathToFile) {
  logging.info(`Converting ${pathToFile}`);
  const convert = process(`cat`, [pathToFile], {});

  return Promise.resolve(
    convert.stdout.on('data', (data) => {
      logging.info(data.toString('utf8'));
    }),
    convert.stderr.on('data', (err) => {
      logging.error(err);
    }),
    convert.on('close', (code) => {
      logging.info(`Conversion finished with status code ${code}`);
    })
  );
}

module.exports = {
  convertFile: (filename) => {
    storage.downloadFile(filename).
      then((localFilename) => {
        logging.info(`File saved to: ${localFilename}`);
      }).
      then(() => convertIncomingFile(`./files/${filename}`)).
      then(() => {
        logging.info(`Coversion of ${filename} complete.`);
      }).
      catch((apiErr) => {
        logging.error(apiErr);
      });
  }
};

正如您所见,info: File saved to: ./files/package.json info: Converting ./files/package.json info: Coversion of package.json complete. info: { <file contents> } info: Conversion finished with status code 0 语句在记录文件内容和转换状态代码语句之前发生。为什么会出现这种情况?如何在“状态代码”声明之后获得“转换完成”声明?

2 个答案:

答案 0 :(得分:2)

Promise.resolve表示返回您提供的已解决的值,它不会像您预期的那样真正异步。查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolvehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise了解更多详细信息

&#13;
&#13;
function convertIncomingFile(pathToFile) {
  logging.info(`Converting ${pathToFile}`);
  const convert = process(`cat`, [pathToFile], {});

  return new Promise((resolve, reject) => {
    convert.stdout.on('data', (data) => {
        logging.info(data.toString('utf8'));
      }),
      convert.stderr.on('data', (err) => {
        logging.error(err);
        reject()
      }),
      convert.on('close', (code) => {
        logging.info(`Conversion finished with status code ${code}`);
        resolve()
      })
  })
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您必须进一步传递convertFile承诺,让下一个then知道它必须等待:

then(() => {
  return convertFile(`./files/${filename}`);
})

和更短的等价物:

then(() => convertFile(`./files/${filename}`))