-1

I am too naive in the JS world. Why is my Javascript Promise not working as expected? I thought console.log("update configs"); won't be executed until console.log("checking bucket"); is completed. Thanks in advance for any help.

Note: the 'checking bucket' function continuous check S3 bucket exists every few seconds until the S3 bucket is created.

process.env.AWS_PROFILE = 'aquarius';
process.env.AWS_SDK_LOAD_CONFIG = 'true';


var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});

// Create S3 service object
s3 = new AWS.S3({apiVersion: '2006-03-01'});

let bucketName = "mybucket.test.com"

// Create S3 service object
var s3 = new AWS.S3({
  apiVersion: '2006-03-01'
});

var promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
      resolve('hello world');
  }, 1);
});

promise.then(function(data) {
  var params = {
    Bucket: bucketName,
    ACL: "public-read"
  };
  s3.createBucket(params, function(err, data) {
    console.log("creating bucket");
    if (err) {
      console.log(err, err.stack); // an error occurred
    } else {
      console.log(data); // successful 
    }
  });
})
.then(function(data) {
  console.log("checking bucket");
  var params = {
    Bucket: bucketName
  };
  s3.waitFor('bucketExists', params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log("bucket exist");           // successful response
  });
})
.then(function(data) {
  console.log("update configs");
  var params2 = {
    Bucket: bucketName,
    ContentMD5: "",
    WebsiteConfiguration: {
      ErrorDocument: {
        Key: "error.html"
      },
      IndexDocument: {
        Suffix: "index.html"
      }
    }
  };
  s3.putBucketWebsite(params2, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else console.log(data); // successful 
  });
});
GreenLake4964
  • 744
  • 9
  • 20
  • 3
    This seems to be the exact same problem as [the one I answered a few minutes ago](https://stackoverflow.com/questions/63461875/method-executed-before-await-method-complete): wrapping code in `then()` does not magically turn it into a Promise. If `s3.createBucket()` doesn't return a Promise, wrapping it in `then()` does not await anything. –  Aug 18 '20 at 04:50
  • 3
    https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property seems to take a callback (e.g., there's no `Promise` returned). Even if there was, you'd be ignoring it in your current code anyway. The function you call after your timeout resolution doesn't return *anything*, in fact, except the implicit `undefined`. – Dave Newton Aug 18 '20 at 04:53

1 Answers1

0

Thanks everyone for the feedback and hints. I found I can retrieve promise object directly from AWS SDK function. Here is the revised code that is working now.

// Create S3 service object
var s3 = new AWS.S3({
  apiVersion: '2006-03-01'
});

var params = {
  Bucket: bucketName,
  ACL: "public-read"
};

var promiseObject = s3.createBucket(params, function(err, data) {
  console.log("creating bucket");
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data); // successful 
  }
}).promise();  // <=== THIS LINE SAVED MY DAY !!

promiseObject.then(function(data) {
  console.log("checking bucket");
  var params = {
    Bucket: bucketName
  };
  s3.waitFor('bucketExists', params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log("bucket exist");           // successful response
  });
})
.then(function(data) {
  console.log("update configs");
  var params2 = {
    Bucket: bucketName,
    ContentMD5: "",
    WebsiteConfiguration: {
      ErrorDocument: {
        Key: "error.html"
      },
      IndexDocument: {
        Suffix: "index.html"
      }
    }
  };
  s3.putBucketWebsite(params2, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else console.log(data); // successful 
  });
})
GreenLake4964
  • 744
  • 9
  • 20
  • 1
    It's the same with `waitFor`, though. And when using callbacks, you should not pass a callback at all, just put the logs in the `then` and `catch` callbacks instead. – Bergi Aug 18 '20 at 05:24
  • 1
    @GreenLake4964 one thing to mention, irrespective of your question. Importing `var AWS = require('aws-sdk');` this whole thing decrease your lambda performance. Import only the module you need. – sphoenix Aug 18 '20 at 06:28