javascript承诺不满足

时间:2017-11-23 03:04:11

标签: javascript json asynchronous callback promise

我是一个新手javascript开发者,这是我第一次作为stackoverflow用户,但我从这里阅读帖子获得了有价值的信息。

我需要加载一个文件,但代码应该等待,因为它的异步性质。我认为Promise可能会起作用并且它几乎可以工作但它仍然没有等待(同步)文件加载。但是,如果没有文件,它会在最后等待。它应该是另一种方式应该等到文件加载。然后继续并运行需要数据的下一个函数。

谁能告诉我为什么我的承诺不起作用?我是否应该使用此承诺或回电?

以下是代码:

// ...

var p = new Promise(function (resolve, reject) {
    let x = getTheData(); // async data but program don’t wait.
    if (!x) { //if no data I want to wait?
        resolve('success');
        console.log('success');
    }else {
        reject('failure');
        console.log('failure');
    }
});

p.then(function () {
    let y = getNewFunctionThatNeedsTheAboveDataToWork();
    res.send('y is not working ' + y);
}).catch(function(){
    console.log('error');
});

return p;

我完全迷失了,任何帮助都会优雅。

1 个答案:

答案 0 :(得分:0)

这里的问题是getData是异步的,所以你需要一些方法来知道它何时完成。这意味着getData需要返回一个promise(更新的方式),或者接受一个回调作为参数(旧的方式)。下面是一个例子,说明getData如何与promises一起使用来通过web调用来获取数据(这在jQuery.get中会更加简单,但是让我们暂时坚持使用纯javascript):

var getData = function() {
  var p = new Promise(function (resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.addEventListener("readystatechange", function () {
      if (this.readyState === 4 && this.status != 200) {
          console.log('Data request returned an error');
          reject('failure');
      } else if (this.readyState === 4 && this.status === 200) {
          resolve(this.responseText);
      }
    });
    xhr.open("GET", "https://httpbin.org/get", true); // true = async
    xhr.send();
  })
  return(p)
}

然后我们可以像这样使用这个函数:

getData().then(function(d) {
  console.log(d);
  // do something useful with d
})

或者,您可以使用回调完成相同的操作:

var getData2 = function (cb) {
  var xhr = new XMLHttpRequest();
  xhr.addEventListener("readystatechange", function () {
    if (this.readyState === 4 && this.status != 200) {
        console.log('Data request returned an error');
        cb(null, "error");
    } else if (this.readyState === 4 && this.status === 200) {
        cb(this.responseText);
    }
  });
  xhr.open("GET", "https://httpbin.org/get", true);
  xhr.send();
}

getData2(function(d, e) {
  if(e) {
    console.log("oops.  there was an error: ", e);
  } else {
    console.log(d);
  }
})

最后,如果getData函数来自其他地方并且您无法更改它,则可以将其从回调样式函数转换为promise样式函数。这是一种方式:

var promiseMe = new Promise(function (resolve, reject) {
  getData2(function(d, e) {
    if(e) {
      reject(e)
    } else {
      resolve(d)
    }
  })
})

promiseMe.then(function(d) {
  console.log(d)
})

修改

以上在浏览器中有效。这是在节点中执行此操作的一种方法:

http = require('http');

var getData = function() {
  var p = new Promise(function (resolve, reject) {
    var data = '';
    http.get('http://httpbin.org/get', function(res) {
        res.on('data', (chunk) => {
            data += chunk;
        });

        res.on('end', () => {
            resolve(data);
        });
    })
  })
  return(p)
}
getData().then(function(d) {
    console.log(d)
})

我希望这些例子能够开始清理。