在多个条件中等待异步函数

Waiting on asynchronous functions within multiple conditionals

我正在从事的流星项目会在满足某些条件时上传文件。无论文件是否上传,一旦 if 语句完成,就必须执行 Meteor.call。由于条件,当我使用回调时会导致大量重复代码。正如下面所写,我希望 Meteor.call 可以在执行 uploadFile 回调之前执行,这将是一个问题。

var data = {
  name: "..."
  //...
}
if(condition){
  uploadFile(parameters, function(error,result){
    if(err) handleError(err);
    else data.url1 = result.secure_url;
}
if(condition2){
  uploadFile(parameters, function(error,result){
    if(err) handleError(err);
    else data.url2 = result.secure_url;
}

/* This Meteor.call needs to wait until both if statements above
   have completed */

Meteor.call('insertData', data, function(error,result){
  //...
}

您可以删除条件并改为实现 Javascript Promises 它们既有趣又奇特,而且它们消除了回调地狱并提供可读的自上而下格式:

http://jsfiddle.net/4v29u4do/1/

这个 fiddle 展示了如何使用 promises 来等待异步回调而不是条件 if 语句

有了 promise,你可以 return 一个新的 promise 作为 promise 的回调,然后继续下去,回调将传递给新的 .then 直到你完成,如果有一路上有任何错误,它会直接跳到 .catch.

function uploadFile(file) {
    return new Promise(function(resolve, reject) {
        // Simulate ASYNC Call for Uploading File
        setTimeout(function() {
            console.log(file + ' Uploaded Successfully!');
            return resolve(file);

            // if (err) {
            //   return reject(err);
            // }
        }, 3000);
    });   
}

var data = {};

uploadFile("filename1")
.then(function(cb) {
    data.url1 = cb;
    return uploadFile("filename2");
})
.then(function(cb) {
    data.url2 = cb;
    return uploadFile("filename5"); 
})
.then(function(cb) {
    data.url3 = cb;
    console.log(data);
    //all done with callbacks
    // Meteor.call("");
})
.catch(function(err) {
    // One of the uploads failed log the err;
});