使用蓝鸟时,操作不正常

时间:2017-03-20 01:44:50

标签: android node.js promise bluebird

完整代码:https://github.com/kenpeter/clip_to_music

基本上,这个简单的nodejs脚本应该按顺序执行这些操作

  1. 重命名所有mp4文件,因此没有不包含空格的文件。

  2. 将所有mp4转换为mp3

  3. 终止adb服务器(带子进程执行)

  4. 启动adb服务器(带子进程执行)

  5. 推送到我的Android手机

  6. 一些示例代码:

    renamePromise
      .then(() => {
        return musicPromise;
      })
      .then(() => {
        return adbKillPromise;
      })
      .then(() => {
        return adbStartPromise;
      })
      .then(() => {
        return adbPushPromise;
      })
      .then(() => {
        console.log('---- all done----');
        process.exit(0);
      });
    

    输出是这样的,乱序

    ; yarn start
    yarn start v0.21.3
    $ node clip_to_music.js 
    
    ---adb kill---
    -- Rename one file --
    /home/kenpeter/Videos/4K Video Downloader/1.mp4
    -- Rename one file --
    /home/kenpeter/Videos/4K Video Downloader/2.mp4
    --- rename all files done ---
    adb push /var/www/html/test/testme/clip_to_music/audio/1.mp3 /sdcard/Music
    adb push /var/www/html/test/testme/clip_to_music/audio/2.mp3 /sdcard/Music
    ---- done push all music ---
    * daemon not running. starting it now on port 5037 *
    * daemon started successfully *
    
    ---adb start---
    single mp3 done!
    
    single mp3 done!
    
    --------- all mp3 conversion done --------
    ---- all done----
    Done in 10.79s.
    

    正如您可以看到上面的输出,超出订单

    1. 它杀死了adb服务器(使用cild进程exec)
    2. 重命名所有mp4文件,因此没有不包含空格的文件。
    3. 将所有音乐推送到我的Android手机
    4. 启动adb服务器(带子进程执行)
    5. 将所有mp4转换为mp3

1 个答案:

答案 0 :(得分:0)

您的代码暗示您已经开始了由musicPromiseadbKillPromiseadbStartPromiseadbPushPromise代表的操作,并且您正在同时运行这些操作时间。因此,他们将按照他们自然完成的任何顺序完成,而你无法直接控制它。

请记住,承诺仅仅是监视异步操作的工具。由于您已经有了承诺,因此您必须已经启动了异步操作,因此您的承诺链根本不会控制活动的顺序。它确实控制了处理结果的顺序,但根本不控制活动本身的顺序。

要真正对操作本身进行排序,您需要不要启动后续操作,直到您想要在其之前执行的操作更像这样:

a().then(b).then(c).catch(err => { /* handler error here */});

a()b()c()是返回承诺的函数,每个函数都会启动相应的异步操作。

作为您的某项操作的示例,请更改此信息:

// adb kill
var adbKillPromise = new Promise((resolve, reject) => {
  exec("adb kill-server", (err, stdout, stderr) => {
    if (err) {
      console.error(err);
      return;
    }

    console.log(stdout);
    console.log('---adb kill---');
    resolve();
  });
});

是一个可以稍后调用的函数:

  // adb kill
  function adbKill() {
    return new Promise((resolve, reject) => {
      exec("adb kill-server", (err, stdout, stderr) => {
        if (err) {
          console.error(err);
          reject(err);
          return;
        }

        console.log(stdout);
        console.log('---adb kill---');
        resolve();
      });
    });
  }

注意,它现在是一个返回一个promise的函数,因此可以根据需要调用它(只有在需要调用它时),并且我还添加了错误处理,以便在出现错误时拒绝它。

并且,为您定义的所有其他变量执行此操作,这些变量对应于您要排序的异步操作之一。然后,你可以这样做:

rename().then(music).then(adbKill).then(adbStart).then(adbPush).then(() => {
    console.log('---- all done----');
    process.exit(0);
}).catch(err => {
    console.log('Error', err);
    process.exit(1);
});